aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrimiano Tucci <primiano@google.com>2019-05-23 14:41:31 +0100
committerPrimiano Tucci <primiano@google.com>2019-05-23 16:52:44 +0000
commit20e879f967d6981814eb935fd081c454a5e34a33 (patch)
tree7262282ab59134a0331936cb6ccab854fc0fdbc0
parentb60b1e905f213926c2f923041027a92d9905bc26 (diff)
parent1ef91c971fde3aa0ee292c425e8e8324a9f29228 (diff)
downloadperfetto-20e879f967d6981814eb935fd081c454a5e34a33.tar.gz
DO NOT MERGE: Merge 1ef91c971fde into qt-dev for Camera
This is to pick-up changes relevant for b/130543265 (see list below). List of changes intended to be merged: fb4d0732 traced: support unique trace session names a48a9dde probes: invalidate seen pids on task_rename event 0b4008a9 process stats: clear more incremental state e004a574 traced: Add initial timestamp c4ecf3eb traced_probes: process tree - handle ClearIncrementalState() 71bce87b Make test trace writer keep its buffer as proper trace packet protos 33868d52 tracing service: add support for issuing periodic ClearIncrementalState ipcs. bdaa962f Producer: add ClearIncrementalState() call/ipc 3f2024e0 ftrace_controller debug print: support >64 cpus (bitset is 128 wide) 248241ee Reduce field id for test trace packet ac6e0d46 incremental state invalidation: trace config & data source descriptor protos a868a078 perfetto_cmd: Avoid indefinite length Dropbox traces b63f61e8 Add config to disable perfetto's default data sources f1d1cd83 Rename Android kill switch Bug: 130543265 Test: unittest, integrationtests + manual Change-Id: Ibdc87afdb22a40a08be3de7b327956cfc3c555af Merged-In: I4b965c9d49f98516dab47dc457458967cb0f6966
-rw-r--r--.travis.yml29
-rw-r--r--Android.bp12
-rw-r--r--BUILD25
-rw-r--r--BUILD.extras21
-rw-r--r--BUILD.gn4
-rw-r--r--gn/protozero_library.gni1
-rw-r--r--include/perfetto/base/BUILD.gn1
-rw-r--r--include/perfetto/base/logging.h3
-rw-r--r--include/perfetto/base/metatrace.h2
-rw-r--r--include/perfetto/base/paged_memory.h1
-rw-r--r--include/perfetto/base/thread_annotations.h40
-rw-r--r--include/perfetto/base/thread_task_runner.h2
-rw-r--r--include/perfetto/protozero/field.h5
-rw-r--r--include/perfetto/protozero/scattered_heap_buffer.h45
-rw-r--r--include/perfetto/tracing/core/data_source_descriptor.h8
-rw-r--r--include/perfetto/tracing/core/producer.h17
-rw-r--r--include/perfetto/tracing/core/trace_config.h102
-rw-r--r--include/perfetto/tracing/core/tracing_service.h319
-rw-r--r--perfetto.rc4
-rw-r--r--protos/BUILD2
-rw-r--r--protos/perfetto/common/BUILD.gn3
-rw-r--r--protos/perfetto/common/descriptor.proto (renamed from src/perfetto_cmd/descriptor.proto)0
-rw-r--r--protos/perfetto/config/data_source_descriptor.proto5
-rw-r--r--protos/perfetto/config/perfetto_config.proto45
-rw-r--r--protos/perfetto/config/trace_config.proto45
-rw-r--r--protos/perfetto/ipc/producer_port.proto14
-rw-r--r--protos/perfetto/trace/chrome/BUILD.gn4
-rw-r--r--protos/perfetto/trace/perfetto_trace.proto54
-rw-r--r--protos/perfetto/trace/trace_packet.proto9
-rw-r--r--src/base/metatrace.cc2
-rw-r--r--src/perfetto_cmd/BUILD.gn2
-rw-r--r--src/perfetto_cmd/config.cc3
-rw-r--r--src/perfetto_cmd/pbtxt_to_pb.cc13
-rw-r--r--src/perfetto_cmd/perfetto_cmd.cc7
-rw-r--r--src/perfetto_cmd/perfetto_config.descriptor.h1081
-rw-r--r--src/perfetto_cmd/trigger_producer.cc6
-rw-r--r--src/perfetto_cmd/trigger_producer.h2
-rw-r--r--src/profiling/memory/heapprofd_producer.h2
-rw-r--r--src/protozero/proto_decoder_unittest.cc15
-rw-r--r--src/traced/probes/ftrace/cpu_reader.cc14
-rw-r--r--src/traced/probes/ftrace/cpu_reader_unittest.cc27
-rw-r--r--src/traced/probes/ftrace/ftrace_controller.cc17
-rw-r--r--src/traced/probes/ftrace/ftrace_metadata.cc7
-rw-r--r--src/traced/probes/ftrace/ftrace_metadata.h2
-rw-r--r--src/traced/probes/probes_data_source.h9
-rw-r--r--src/traced/probes/probes_producer.cc21
-rw-r--r--src/traced/probes/probes_producer.h2
-rw-r--r--src/traced/probes/ps/process_stats_data_source.cc34
-rw-r--r--src/traced/probes/ps/process_stats_data_source.h13
-rw-r--r--src/traced/probes/ps/process_stats_data_source_unittest.cc238
-rw-r--r--src/traced/service/lazy_producer.h2
-rw-r--r--src/tracing/core/data_source_descriptor.cc18
-rw-r--r--src/tracing/core/trace_buffer.h11
-rw-r--r--src/tracing/core/trace_config.cc151
-rw-r--r--src/tracing/core/trace_writer_for_testing.cc46
-rw-r--r--src/tracing/core/trace_writer_for_testing.h5
-rw-r--r--src/tracing/core/tracing_service_impl.cc137
-rw-r--r--src/tracing/core/tracing_service_impl.h20
-rw-r--r--src/tracing/core/tracing_service_impl_unittest.cc169
-rw-r--r--src/tracing/ipc/producer/producer_ipc_client_impl.cc22
-rw-r--r--src/tracing/ipc/service/producer_ipc_service.cc17
-rw-r--r--src/tracing/ipc/service/producer_ipc_service.h3
-rw-r--r--src/tracing/test/mock_producer.cc4
-rw-r--r--src/tracing/test/mock_producer.h5
-rw-r--r--src/tracing/test/tracing_integration_test.cc3
-rw-r--r--test/end_to_end_integrationtest.cc16
-rw-r--r--test/end_to_end_shared_memory_fuzzer.cc1
-rw-r--r--test/fake_producer.h2
-rwxr-xr-xtools/gen_build3
-rwxr-xr-xtools/gen_tracing_cpp_headers_from_protos6
70 files changed, 2108 insertions, 872 deletions
diff --git a/.travis.yml b/.travis.yml
index 256881cb4..2d53e2208 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -45,36 +45,33 @@ matrix:
# compiler: clang
# env: CFG=mac-clang-x86_64-ubsan GN_ARGS="is_debug=false is_ubsan=true"
- os: linux
- dist: trusty
+ dist: xenial
sudo: false
- # When setting compiler: clang Travis pull a newer version of clang than
- # the version that is shipped with Trusty. This is good for all the other
- # configs, but we want to keep at least one target in the matrix to match
- # the default version of clang that we have on our workstations.
+ # Test the system-version of clang, not our own at least in this config.
addons:
apt:
packages:
- clang
env: CFG=linux_trusty-clang-x86_64-debug GN_ARGS="is_debug=true is_hermetic_clang=false"
- os: linux
- dist: trusty
+ dist: xenial
sudo: false
compiler: clang
env: CFG=linux_trusty-clang-x86_64-tsan GN_ARGS="is_debug=false is_tsan=true"
- os: linux
- dist: trusty
+ dist: xenial
sudo: false
compiler: clang
env: CFG=linux_trusty-clang-x86_64-msan GN_ARGS="is_debug=false is_msan=true"
# TODO(b/117093687): ubsan always times out in Travis.
# Re-enable once that is fixed.
- os: linux
- dist: trusty
+ dist: xenial
sudo: true
compiler: clang
env: CFG=linux_trusty-clang-x86_64-asan_lsan GN_ARGS="is_debug=false is_asan=true is_lsan=true"
- os: linux
- dist: trusty
+ dist: xenial
sudo: false
addons:
apt:
@@ -84,27 +81,27 @@ matrix:
- g++-7
env: CFG=linux_trusty-gcc7-x86_64-release GN_ARGS="is_debug=false is_clang=false use_custom_libcxx=false cc=\"gcc-7\" cxx=\"g++-7\""
- os: linux
- dist: trusty
+ dist: xenial
sudo: false
compiler: clang
env: CFG=android-clang-arm-release GN_ARGS="is_debug=false target_os=\"android\" target_cpu=\"arm\""
- os: linux
- dist: trusty
+ dist: xenial
sudo: true
compiler: clang
env: CFG=android-clang-arm-asan GN_ARGS="is_debug=false target_os=\"android\" target_cpu=\"arm\" is_asan=true"
- os: linux
- dist: trusty
+ dist: xenial
sudo: true
compiler: clang
env: CFG=linux_trusty-clang-x86_64-libfuzzer GN_ARGS="is_clang=true is_debug=false is_fuzzer=true is_asan=true"
- os: linux
- dist: trusty
+ dist: xenial
sudo: false
compiler: clang
env: CFG=ui-clang-x86_64-release GN_ARGS="is_debug=false is_clang=true"
- os: linux
- dist: trusty
+ dist: xenial
sudo: false
compiler: clang
env: CFG=ui-clang-x86_64-debug GN_ARGS="is_debug=true is_clang=true"
@@ -185,7 +182,9 @@ script:
"out/dist/$TEST_TARGET"
done
BENCHMARK_FUNCTIONAL_TEST_ONLY=true out/dist/perfetto_benchmarks
- tools/diff_test_trace_processor.py out/dist/trace_processor_shell
+
+ tools/diff_test_trace_processor.py --test-type=queries out/dist/trace_processor_shell
+ tools/diff_test_trace_processor.py --test-type=metrics out/dist/trace_processor_shell
fi
after_script:
diff --git a/Android.bp b/Android.bp
index cbbed4615..14284b767 100644
--- a/Android.bp
+++ b/Android.bp
@@ -756,6 +756,7 @@ genrule {
srcs: [
"protos/perfetto/common/android_log_constants.proto",
"protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/descriptor.proto",
"protos/perfetto/common/observable_events.proto",
"protos/perfetto/common/sys_stats_counters.proto",
"protos/perfetto/common/trace_stats.proto",
@@ -767,6 +768,7 @@ genrule {
out: [
"external/perfetto/protos/perfetto/common/android_log_constants.pb.cc",
"external/perfetto/protos/perfetto/common/commit_data_request.pb.cc",
+ "external/perfetto/protos/perfetto/common/descriptor.pb.cc",
"external/perfetto/protos/perfetto/common/observable_events.pb.cc",
"external/perfetto/protos/perfetto/common/sys_stats_counters.pb.cc",
"external/perfetto/protos/perfetto/common/trace_stats.pb.cc",
@@ -779,6 +781,7 @@ genrule {
srcs: [
"protos/perfetto/common/android_log_constants.proto",
"protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/descriptor.proto",
"protos/perfetto/common/observable_events.proto",
"protos/perfetto/common/sys_stats_counters.proto",
"protos/perfetto/common/trace_stats.proto",
@@ -790,6 +793,7 @@ genrule {
out: [
"external/perfetto/protos/perfetto/common/android_log_constants.pb.h",
"external/perfetto/protos/perfetto/common/commit_data_request.pb.h",
+ "external/perfetto/protos/perfetto/common/descriptor.pb.h",
"external/perfetto/protos/perfetto/common/observable_events.pb.h",
"external/perfetto/protos/perfetto/common/sys_stats_counters.pb.h",
"external/perfetto/protos/perfetto/common/trace_stats.pb.h",
@@ -805,6 +809,7 @@ genrule {
srcs: [
"protos/perfetto/common/android_log_constants.proto",
"protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/descriptor.proto",
"protos/perfetto/common/observable_events.proto",
"protos/perfetto/common/sys_stats_counters.proto",
"protos/perfetto/common/trace_stats.proto",
@@ -817,6 +822,7 @@ genrule {
out: [
"external/perfetto/protos/perfetto/common/android_log_constants.pbzero.cc",
"external/perfetto/protos/perfetto/common/commit_data_request.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/descriptor.pbzero.cc",
"external/perfetto/protos/perfetto/common/observable_events.pbzero.cc",
"external/perfetto/protos/perfetto/common/sys_stats_counters.pbzero.cc",
"external/perfetto/protos/perfetto/common/trace_stats.pbzero.cc",
@@ -829,6 +835,7 @@ genrule {
srcs: [
"protos/perfetto/common/android_log_constants.proto",
"protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/descriptor.proto",
"protos/perfetto/common/observable_events.proto",
"protos/perfetto/common/sys_stats_counters.proto",
"protos/perfetto/common/trace_stats.proto",
@@ -841,6 +848,7 @@ genrule {
out: [
"external/perfetto/protos/perfetto/common/android_log_constants.pbzero.h",
"external/perfetto/protos/perfetto/common/commit_data_request.pbzero.h",
+ "external/perfetto/protos/perfetto/common/descriptor.pbzero.h",
"external/perfetto/protos/perfetto/common/observable_events.pbzero.h",
"external/perfetto/protos/perfetto/common/sys_stats_counters.pbzero.h",
"external/perfetto/protos/perfetto/common/trace_stats.pbzero.h",
@@ -2412,7 +2420,6 @@ genrule {
genrule {
name: "perfetto_src_perfetto_cmd_protos_gen",
srcs: [
- "src/perfetto_cmd/descriptor.proto",
"src/perfetto_cmd/perfetto_cmd_state.proto",
],
tools: [
@@ -2420,7 +2427,6 @@ genrule {
],
cmd: "mkdir -p $(genDir)/external/perfetto && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto --proto_path=external/perfetto/ $(in)",
out: [
- "external/perfetto/src/perfetto_cmd/descriptor.pb.cc",
"external/perfetto/src/perfetto_cmd/perfetto_cmd_state.pb.cc",
],
}
@@ -2429,7 +2435,6 @@ genrule {
genrule {
name: "perfetto_src_perfetto_cmd_protos_gen_headers",
srcs: [
- "src/perfetto_cmd/descriptor.proto",
"src/perfetto_cmd/perfetto_cmd_state.proto",
],
tools: [
@@ -2437,7 +2442,6 @@ genrule {
],
cmd: "mkdir -p $(genDir)/external/perfetto && $(location aprotoc) --cpp_out=$(genDir)/external/perfetto --proto_path=external/perfetto/ $(in)",
out: [
- "external/perfetto/src/perfetto_cmd/descriptor.pb.h",
"external/perfetto/src/perfetto_cmd/perfetto_cmd_state.pb.h",
],
export_include_dirs: [
diff --git a/BUILD b/BUILD
index 80a74193f..0e0d03a97 100644
--- a/BUILD
+++ b/BUILD
@@ -85,6 +85,7 @@ cc_library(
"include/perfetto/base/string_writer.h",
"include/perfetto/base/task_runner.h",
"include/perfetto/base/temp_file.h",
+ "include/perfetto/base/thread_annotations.h",
"include/perfetto/base/thread_checker.h",
"include/perfetto/base/thread_task_runner.h",
"include/perfetto/base/thread_utils.h",
@@ -283,6 +284,7 @@ cc_library(
"include/perfetto/base/string_writer.h",
"include/perfetto/base/task_runner.h",
"include/perfetto/base/temp_file.h",
+ "include/perfetto/base/thread_annotations.h",
"include/perfetto/base/thread_checker.h",
"include/perfetto/base/thread_task_runner.h",
"include/perfetto/base/thread_utils.h",
@@ -357,6 +359,7 @@ cc_binary(
"include/perfetto/base/string_writer.h",
"include/perfetto/base/task_runner.h",
"include/perfetto/base/temp_file.h",
+ "include/perfetto/base/thread_annotations.h",
"include/perfetto/base/thread_checker.h",
"include/perfetto/base/thread_task_runner.h",
"include/perfetto/base/thread_utils.h",
@@ -564,6 +567,7 @@ cc_binary(
"include/perfetto/base/string_writer.h",
"include/perfetto/base/task_runner.h",
"include/perfetto/base/temp_file.h",
+ "include/perfetto/base/thread_annotations.h",
"include/perfetto/base/thread_checker.h",
"include/perfetto/base/thread_task_runner.h",
"include/perfetto/base/thread_utils.h",
@@ -790,3 +794,24 @@ py_binary(
],
main = "tools/gen_merged_sql_metrics.py",
)
+
+load("//security/fuzzing/blaze:cc_fuzz_target.bzl", "cc_fuzz_target")
+
+cc_fuzz_target(
+ name = "trace_parsing_fuzzer",
+ srcs = ["src/trace_processor/trace_parsing_fuzzer.cc"],
+ componentid = 323270,
+ deps = [
+ ":trace_processor",
+ "//third_party/perfetto/protos:trace_processor_cc_proto",
+ ],
+)
+
+cc_fuzz_target(
+ name = "proto_decoder_fuzzer",
+ srcs = ["src/protozero/proto_decoder_fuzzer.cc"],
+ componentid = 323270,
+ deps = [
+ ":trace_processor",
+ ],
+)
diff --git a/BUILD.extras b/BUILD.extras
index cda25fb5c..d18d9a24b 100644
--- a/BUILD.extras
+++ b/BUILD.extras
@@ -17,3 +17,24 @@ py_binary(
],
main = "tools/gen_merged_sql_metrics.py",
)
+
+load("//security/fuzzing/blaze:cc_fuzz_target.bzl", "cc_fuzz_target")
+
+cc_fuzz_target(
+ name = "trace_parsing_fuzzer",
+ srcs = ["src/trace_processor/trace_parsing_fuzzer.cc"],
+ componentid = 323270,
+ deps = [
+ ":trace_processor",
+ "//third_party/perfetto/protos:trace_processor_cc_proto",
+ ],
+)
+
+cc_fuzz_target(
+ name = "proto_decoder_fuzzer",
+ srcs = ["src/protozero/proto_decoder_fuzzer.cc"],
+ componentid = 323270,
+ deps = [
+ ":trace_processor",
+ ],
+)
diff --git a/BUILD.gn b/BUILD.gn
index 084bf9d11..d23019f7f 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -138,7 +138,9 @@ test("perfetto_unittests") {
deps += [ "src/profiling/memory:unittests" ]
}
if (perfetto_build_standalone && !is_android) {
- deps += [ "src/trace_processor:unittests" ]
+ deps += [
+ "src/trace_processor:unittests",
+ ]
}
}
diff --git a/gn/protozero_library.gni b/gn/protozero_library.gni
index 89e7969fc..d2c01b92d 100644
--- a/gn/protozero_library.gni
+++ b/gn/protozero_library.gni
@@ -49,6 +49,7 @@ template("protozero_library") {
"sources",
"testonly",
"visibility",
+ "generate_descriptor",
])
}
}
diff --git a/include/perfetto/base/BUILD.gn b/include/perfetto/base/BUILD.gn
index 65df2f024..0540e0f66 100644
--- a/include/perfetto/base/BUILD.gn
+++ b/include/perfetto/base/BUILD.gn
@@ -38,6 +38,7 @@ source_set("base") {
"string_writer.h",
"task_runner.h",
"temp_file.h",
+ "thread_annotations.h",
"thread_checker.h",
"thread_task_runner.h",
"thread_utils.h",
diff --git a/include/perfetto/base/logging.h b/include/perfetto/base/logging.h
index 35896ce75..131f58908 100644
--- a/include/perfetto/base/logging.h
+++ b/include/perfetto/base/logging.h
@@ -169,6 +169,8 @@ constexpr const char* kLogFmt[] = {"\x1b[2m", "\x1b[39m", "\x1b[32m\x1b[1m",
PERFETTO_IMMEDIATE_CRASH(); \
} while (0)
+#define PERFETTO_DFATAL_OR_ELOG(...) PERFETTO_DFATAL(__VA_ARGS__)
+
#else
#define PERFETTO_DCHECK(x) \
@@ -176,6 +178,7 @@ constexpr const char* kLogFmt[] = {"\x1b[2m", "\x1b[39m", "\x1b[32m\x1b[1m",
} while (false && (x))
#define PERFETTO_DFATAL(...) ::perfetto::base::ignore_result(__VA_ARGS__)
+#define PERFETTO_DFATAL_OR_ELOG(...) PERFETTO_ELOG(__VA_ARGS__)
#endif // PERFETTO_DCHECK_IS_ON()
diff --git a/include/perfetto/base/metatrace.h b/include/perfetto/base/metatrace.h
index 9659b9007..116a160a8 100644
--- a/include/perfetto/base/metatrace.h
+++ b/include/perfetto/base/metatrace.h
@@ -29,6 +29,8 @@ namespace base {
class MetaTrace {
public:
+ static constexpr uint32_t kMainThreadCpu = 255;
+
MetaTrace(const char* evt_name, size_t cpu) : evt_name_(evt_name), cpu_(cpu) {
WriteEvent('B', evt_name, cpu);
}
diff --git a/include/perfetto/base/paged_memory.h b/include/perfetto/base/paged_memory.h
index ea2aaae8f..f994ea5ed 100644
--- a/include/perfetto/base/paged_memory.h
+++ b/include/perfetto/base/paged_memory.h
@@ -78,6 +78,7 @@ class PagedMemory {
inline void* Get() const noexcept { return p_; }
inline bool IsValid() const noexcept { return !!p_; }
+ inline size_t size() const noexcept { return size_; }
private:
PagedMemory(char* p, size_t size);
diff --git a/include/perfetto/base/thread_annotations.h b/include/perfetto/base/thread_annotations.h
new file mode 100644
index 000000000..b5d367194
--- /dev/null
+++ b/include/perfetto/base/thread_annotations.h
@@ -0,0 +1,40 @@
+/*
+ * 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_BASE_THREAD_ANNOTATIONS_H_
+#define INCLUDE_PERFETTO_BASE_THREAD_ANNOTATIONS_H_
+
+#include "perfetto/base/build_config.h"
+
+// Windows TSAN doesn't currently support these annotations.
+#if defined(THREAD_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+extern "C" {
+void AnnotateBenignRaceSized(const char* file,
+ int line,
+ unsigned long address,
+ unsigned long size,
+ const char* description);
+}
+
+#define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description) \
+ AnnotateBenignRaceSized(__FILE__, __LINE__, \
+ reinterpret_cast<unsigned long>(pointer), size, \
+ description);
+#else // defined(ADDRESS_SANITIZER)
+#define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description)
+#endif // defined(ADDRESS_SANITIZER)
+
+#endif // INCLUDE_PERFETTO_BASE_THREAD_ANNOTATIONS_H_
diff --git a/include/perfetto/base/thread_task_runner.h b/include/perfetto/base/thread_task_runner.h
index 7992eeb6b..db49a6103 100644
--- a/include/perfetto/base/thread_task_runner.h
+++ b/include/perfetto/base/thread_task_runner.h
@@ -50,7 +50,7 @@ class ThreadTaskRunner {
//
// Warning: do not call Quit() on the returned runner pointer, the termination
// should be handled exclusively by this class' destructor.
- UnixTaskRunner* get() { return task_runner_; }
+ UnixTaskRunner* get() const { return task_runner_; }
private:
ThreadTaskRunner();
diff --git a/include/perfetto/protozero/field.h b/include/perfetto/protozero/field.h
index cbb48e6ca..9c6da8d07 100644
--- a/include/perfetto/protozero/field.h
+++ b/include/perfetto/protozero/field.h
@@ -19,6 +19,8 @@
#include <stdint.h>
+#include <string>
+
#include "perfetto/base/logging.h"
#include "perfetto/protozero/contiguous_memory_range.h"
#include "perfetto/protozero/proto_utils.h"
@@ -34,6 +36,7 @@ struct ConstChars {
// Allow implicit conversion to perfetto's base::StringView without depending
// on perfetto/base or viceversa.
static constexpr bool kConvertibleToStringView = true;
+ std::string ToStdString() const { return std::string(data, size); }
const char* data;
size_t size;
@@ -112,6 +115,8 @@ class Field {
return ConstChars{reinterpret_cast<const char*>(data()), size_};
}
+ inline std::string as_std_string() const { return as_string().ToStdString(); }
+
inline ConstBytes as_bytes() const {
PERFETTO_DCHECK(!valid() ||
type() == proto_utils::ProtoWireType::kLengthDelimited);
diff --git a/include/perfetto/protozero/scattered_heap_buffer.h b/include/perfetto/protozero/scattered_heap_buffer.h
index d88f7e63b..7f3906ed9 100644
--- a/include/perfetto/protozero/scattered_heap_buffer.h
+++ b/include/perfetto/protozero/scattered_heap_buffer.h
@@ -18,6 +18,7 @@
#define INCLUDE_PERFETTO_PROTOZERO_SCATTERED_HEAP_BUFFER_H_
#include <memory>
+#include <string>
#include <vector>
#include "perfetto/base/export.h"
@@ -26,6 +27,8 @@
namespace protozero {
+class Message;
+
class PERFETTO_EXPORT ScatteredHeapBuffer
: public protozero::ScatteredStreamWriter::Delegate {
public:
@@ -86,6 +89,48 @@ class PERFETTO_EXPORT ScatteredHeapBuffer
std::vector<Slice> slices_;
};
+// Helper function to create heap-based protozero messages in one line.
+// This is a convenience wrapper, mostly for tests, to avoid having to do:
+// MyMessage msg;
+// ScatteredHeapBuffer shb;
+// ScatteredStreamWriter writer(&shb);
+// shb.set_writer(&writer);
+// msg.Reset(&shb);
+// Just to get an easily serializable message. Instead this allows simply:
+// HeapBuffered<MyMessage> msg;
+// msg->set_stuff(...);
+// msg->SerializeAsString();
+template <typename T = ::protozero::Message>
+class HeapBuffered {
+ public:
+ HeapBuffered() : shb_(4096, 4096), writer_(&shb_) {
+ shb_.set_writer(&writer_);
+ msg_.Reset(&writer_);
+ }
+
+ // This can't be neither copied nor moved because Message hands out pointers
+ // to itself when creating submessages.
+ HeapBuffered(const HeapBuffered&) = delete;
+ HeapBuffered& operator=(const HeapBuffered&) = delete;
+ HeapBuffered(HeapBuffered&&) = delete;
+ HeapBuffered& operator=(HeapBuffered&&) = delete;
+
+ T* get() { return &msg_; }
+ T* operator->() { return &msg_; }
+
+ std::vector<uint8_t> SerializeAsArray() { return shb_.StitchSlices(); }
+
+ std::string SerializeAsString() {
+ auto vec = SerializeAsArray();
+ return std::string(reinterpret_cast<const char*>(vec.data()), vec.size());
+ }
+
+ private:
+ ScatteredHeapBuffer shb_;
+ ScatteredStreamWriter writer_;
+ T msg_;
+};
+
} // namespace protozero
#endif // INCLUDE_PERFETTO_PROTOZERO_SCATTERED_HEAP_BUFFER_H_
diff --git a/include/perfetto/tracing/core/data_source_descriptor.h b/include/perfetto/tracing/core/data_source_descriptor.h
index 8cbab7390..af161ff14 100644
--- a/include/perfetto/tracing/core/data_source_descriptor.h
+++ b/include/perfetto/tracing/core/data_source_descriptor.h
@@ -70,10 +70,18 @@ class PERFETTO_EXPORT DataSourceDescriptor {
bool will_notify_on_start() const { return will_notify_on_start_; }
void set_will_notify_on_start(bool value) { will_notify_on_start_ = value; }
+ bool handles_incremental_state_clear() const {
+ return handles_incremental_state_clear_;
+ }
+ void set_handles_incremental_state_clear(bool value) {
+ handles_incremental_state_clear_ = value;
+ }
+
private:
std::string name_ = {};
bool will_notify_on_stop_ = {};
bool will_notify_on_start_ = {};
+ bool handles_incremental_state_clear_ = {};
// Allows to preserve unknown protobuf fields for compatibility
// with future versions of .proto files.
diff --git a/include/perfetto/tracing/core/producer.h b/include/perfetto/tracing/core/producer.h
index 2c8e6f2f9..f383b7ec0 100644
--- a/include/perfetto/tracing/core/producer.h
+++ b/include/perfetto/tracing/core/producer.h
@@ -104,6 +104,23 @@ class PERFETTO_EXPORT Producer {
virtual void Flush(FlushRequestID,
const DataSourceInstanceID* data_source_ids,
size_t num_data_sources) = 0;
+
+ // Called by the service to instruct the given data sources to stop referring
+ // to any trace contents emitted so far. The intent is that after processing
+ // this call, the rest of the trace should be parsable even if all of the
+ // packets emitted so far have been lost (for example due to ring buffer
+ // overwrites).
+ //
+ // Called only for Producers with active data sources that have opted in by
+ // setting |handles_incremental_state_clear| in their DataSourceDescriptor.
+ //
+ // The way this call is handled is up to the individual Producer
+ // implementation. Some might wish to emit invalidation markers in the trace
+ // (see TracePacket.incremental_state_cleared for an existing field), and
+ // handle them when parsing the trace.
+ virtual void ClearIncrementalState(
+ const DataSourceInstanceID* data_source_ids,
+ size_t num_data_sources) = 0;
};
} // namespace perfetto
diff --git a/include/perfetto/tracing/core/trace_config.h b/include/perfetto/tracing/core/trace_config.h
index 8d6cbbb6a..a48cd2245 100644
--- a/include/perfetto/tracing/core/trace_config.h
+++ b/include/perfetto/tracing/core/trace_config.h
@@ -56,11 +56,13 @@ class AndroidPowerConfig;
class AndroidLogConfig;
class TestConfig;
class TestConfig_DummyFields;
+class TraceConfig_BuiltinDataSource;
class TraceConfig_ProducerConfig;
class TraceConfig_StatsdMetadata;
class TraceConfig_GuardrailOverrides;
class TraceConfig_TriggerConfig;
class TraceConfig_TriggerConfig_Trigger;
+class TraceConfig_IncrementalStateConfig;
} // namespace protos
} // namespace perfetto
@@ -147,6 +149,46 @@ class PERFETTO_EXPORT TraceConfig {
std::string unknown_fields_;
};
+ class PERFETTO_EXPORT BuiltinDataSource {
+ public:
+ BuiltinDataSource();
+ ~BuiltinDataSource();
+ BuiltinDataSource(BuiltinDataSource&&) noexcept;
+ BuiltinDataSource& operator=(BuiltinDataSource&&);
+ BuiltinDataSource(const BuiltinDataSource&);
+ BuiltinDataSource& operator=(const BuiltinDataSource&);
+ bool operator==(const BuiltinDataSource&) const;
+ bool operator!=(const BuiltinDataSource& other) const {
+ return !(*this == other);
+ }
+
+ // Conversion methods from/to the corresponding protobuf types.
+ void FromProto(const perfetto::protos::TraceConfig_BuiltinDataSource&);
+ void ToProto(perfetto::protos::TraceConfig_BuiltinDataSource*) const;
+
+ bool disable_clock_snapshotting() const {
+ return disable_clock_snapshotting_;
+ }
+ void set_disable_clock_snapshotting(bool value) {
+ disable_clock_snapshotting_ = value;
+ }
+
+ bool disable_trace_config() const { return disable_trace_config_; }
+ void set_disable_trace_config(bool value) { disable_trace_config_ = value; }
+
+ bool disable_system_info() const { return disable_system_info_; }
+ void set_disable_system_info(bool value) { disable_system_info_ = value; }
+
+ private:
+ bool disable_clock_snapshotting_ = {};
+ bool disable_trace_config_ = {};
+ bool disable_system_info_ = {};
+
+ // Allows to preserve unknown protobuf fields for compatibility
+ // with future versions of .proto files.
+ std::string unknown_fields_;
+ };
+
enum LockdownModeOperation {
LOCKDOWN_UNCHANGED = 0,
LOCKDOWN_CLEAR = 1,
@@ -358,6 +400,34 @@ class PERFETTO_EXPORT TraceConfig {
std::string unknown_fields_;
};
+ class PERFETTO_EXPORT IncrementalStateConfig {
+ public:
+ IncrementalStateConfig();
+ ~IncrementalStateConfig();
+ IncrementalStateConfig(IncrementalStateConfig&&) noexcept;
+ IncrementalStateConfig& operator=(IncrementalStateConfig&&);
+ IncrementalStateConfig(const IncrementalStateConfig&);
+ IncrementalStateConfig& operator=(const IncrementalStateConfig&);
+ bool operator==(const IncrementalStateConfig&) const;
+ bool operator!=(const IncrementalStateConfig& other) const {
+ return !(*this == other);
+ }
+
+ // Conversion methods from/to the corresponding protobuf types.
+ void FromProto(const perfetto::protos::TraceConfig_IncrementalStateConfig&);
+ void ToProto(perfetto::protos::TraceConfig_IncrementalStateConfig*) const;
+
+ uint32_t clear_period_ms() const { return clear_period_ms_; }
+ void set_clear_period_ms(uint32_t value) { clear_period_ms_ = value; }
+
+ private:
+ uint32_t clear_period_ms_ = {};
+
+ // Allows to preserve unknown protobuf fields for compatibility
+ // with future versions of .proto files.
+ std::string unknown_fields_;
+ };
+
TraceConfig();
~TraceConfig();
TraceConfig(TraceConfig&&) noexcept;
@@ -391,6 +461,13 @@ class PERFETTO_EXPORT TraceConfig {
return &data_sources_.back();
}
+ const BuiltinDataSource& builtin_data_sources() const {
+ return builtin_data_sources_;
+ }
+ BuiltinDataSource* mutable_builtin_data_sources() {
+ return &builtin_data_sources_;
+ }
+
uint32_t duration_ms() const { return duration_ms_; }
void set_duration_ms(uint32_t value) { duration_ms_ = value; }
@@ -443,13 +520,6 @@ class PERFETTO_EXPORT TraceConfig {
uint32_t flush_timeout_ms() const { return flush_timeout_ms_; }
void set_flush_timeout_ms(uint32_t value) { flush_timeout_ms_ = value; }
- bool disable_clock_snapshotting() const {
- return disable_clock_snapshotting_;
- }
- void set_disable_clock_snapshotting(bool value) {
- disable_clock_snapshotting_ = value;
- }
-
bool notify_traceur() const { return notify_traceur_; }
void set_notify_traceur(bool value) { notify_traceur_ = value; }
@@ -471,14 +541,29 @@ class PERFETTO_EXPORT TraceConfig {
return &activate_triggers_.back();
}
+ const IncrementalStateConfig& incremental_state_config() const {
+ return incremental_state_config_;
+ }
+ IncrementalStateConfig* mutable_incremental_state_config() {
+ return &incremental_state_config_;
+ }
+
bool allow_user_build_tracing() const { return allow_user_build_tracing_; }
void set_allow_user_build_tracing(bool value) {
allow_user_build_tracing_ = value;
}
+ const std::string& unique_session_name() const {
+ return unique_session_name_;
+ }
+ void set_unique_session_name(const std::string& value) {
+ unique_session_name_ = value;
+ }
+
private:
std::vector<BufferConfig> buffers_;
std::vector<DataSource> data_sources_;
+ BuiltinDataSource builtin_data_sources_ = {};
uint32_t duration_ms_ = {};
bool enable_extra_guardrails_ = {};
LockdownModeOperation lockdown_mode_ = {};
@@ -491,11 +576,12 @@ class PERFETTO_EXPORT TraceConfig {
bool deferred_start_ = {};
uint32_t flush_period_ms_ = {};
uint32_t flush_timeout_ms_ = {};
- bool disable_clock_snapshotting_ = {};
bool notify_traceur_ = {};
TriggerConfig trigger_config_ = {};
std::vector<std::string> activate_triggers_;
+ IncrementalStateConfig incremental_state_config_ = {};
bool allow_user_build_tracing_ = {};
+ std::string unique_session_name_ = {};
// Allows to preserve unknown protobuf fields for compatibility
// with future versions of .proto files.
diff --git a/include/perfetto/tracing/core/tracing_service.h b/include/perfetto/tracing/core/tracing_service.h
index c2eb971fa..3d276989e 100644
--- a/include/perfetto/tracing/core/tracing_service.h
+++ b/include/perfetto/tracing/core/tracing_service.h
@@ -45,6 +45,165 @@ class TraceWriter;
// TODO: for the moment this assumes that all the calls happen on the same
// thread/sequence. Not sure this will be the case long term in Chrome.
+// The API for the Producer port of the Service.
+// Subclassed by:
+// 1. The tracing_service_impl.cc business logic when returning it in response
+// to the ConnectProducer() method.
+// 2. The transport layer (e.g., src/ipc) when the producer and
+// the service don't talk locally but via some IPC mechanism.
+class PERFETTO_EXPORT ProducerEndpoint {
+ public:
+ virtual ~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 UnregisterDataSource(const std::string& name) = 0;
+
+ // Associate the trace writer with the given |writer_id| with
+ // |target_buffer|. The service may use this information to retrieve and
+ // copy uncommitted chunks written by the trace writer into its associated
+ // buffer, e.g. when a producer process crashes or when a flush is
+ // necessary.
+ virtual void RegisterTraceWriter(uint32_t writer_id,
+ uint32_t target_buffer) = 0;
+
+ // Remove the association of the trace writer previously created via
+ // RegisterTraceWriter.
+ virtual void UnregisterTraceWriter(uint32_t writer_id) = 0;
+
+ // Called by the Producer to signal that some pages in the shared memory
+ // buffer (shared between Service and Producer) have changed.
+ // When the Producer and the Service are hosted in the same process and
+ // hence potentially live on the same task runner, This method must call
+ // TracingServiceImpl's CommitData synchronously, without any PostTask()s,
+ // if on the same thread. This is to avoid a deadlock where the Producer
+ // exhausts its SMB and stalls waiting for the service to catch up with
+ // reads, but the Service never gets to that because it lives on the same
+ // thread.
+ using CommitDataCallback = std::function<void()>;
+ virtual void CommitData(const CommitDataRequest&,
+ CommitDataCallback callback = {}) = 0;
+
+ virtual SharedMemory* shared_memory() const = 0;
+
+ // Size of shared memory buffer pages. It's always a multiple of 4K.
+ // See shared_memory_abi.h
+ virtual size_t shared_buffer_page_size_kb() const = 0;
+
+ // Creates a trace writer, which allows to create events, handling the
+ // underying shared memory buffer and signalling to the Service. This method
+ // is thread-safe but the returned object is not. A TraceWriter should be
+ // used only from a single thread, or the caller has to handle sequencing
+ // via a mutex or equivalent. This method can only be called if
+ // TracingService::ConnectProducer was called with |in_process=true|.
+ // Args:
+ // |target_buffer| is the target buffer ID where the data produced by the
+ // writer should be stored by the tracing service. This value is passed
+ // upon creation of the data source (StartDataSource()) in the
+ // DataSourceConfig.target_buffer().
+ virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
+ BufferID target_buffer) = 0;
+
+ // If TracingService::ConnectProducer is called with |in_process=true|,
+ // this returns the producer's SharedMemoryArbiter which can be used
+ // to create TraceWriters which is able to directly commit chunks
+ // without going through an IPC layer.
+ virtual SharedMemoryArbiter* GetInProcessShmemArbiter() = 0;
+
+ // Called in response to a Producer::Flush(request_id) call after all data
+ // for the flush request has been committed.
+ virtual void NotifyFlushComplete(FlushRequestID) = 0;
+
+ // Called in response to one or more Producer::StartDataSource(),
+ // if the data source registered setting the flag
+ // DataSourceDescriptor.will_notify_on_start.
+ virtual void NotifyDataSourceStarted(DataSourceInstanceID) = 0;
+
+ // Called in response to one or more Producer::StopDataSource(),
+ // if the data source registered setting the flag
+ // DataSourceDescriptor.will_notify_on_stop.
+ virtual void NotifyDataSourceStopped(DataSourceInstanceID) = 0;
+
+ // This informs the service to activate any of these triggers if any tracing
+ // session was waiting for them.
+ virtual void ActivateTriggers(const std::vector<std::string>&) = 0;
+}; // class ProducerEndpoint.
+
+// The API for the Consumer port of the Service.
+// Subclassed by:
+// 1. The tracing_service_impl.cc business logic when returning it in response
+// to
+// the ConnectConsumer() method.
+// 2. The transport layer (e.g., src/ipc) when the consumer and
+// the service don't talk locally but via some IPC mechanism.
+class ConsumerEndpoint {
+ public:
+ virtual ~ConsumerEndpoint();
+
+ // Enables tracing with the given TraceConfig. The ScopedFile argument is
+ // used only when TraceConfig.write_into_file == true.
+ // If TraceConfig.deferred_start == true data sources are configured via
+ // SetupDataSource() but are not started until StartTracing() is called.
+ // This is to support pre-initialization and fast triggering of traces.
+ // The ScopedFile argument is used only when TraceConfig.write_into_file
+ // == true.
+ virtual void EnableTracing(const TraceConfig&,
+ base::ScopedFile = base::ScopedFile()) = 0;
+
+ // Update the trace config of an existing tracing session; only a subset
+ // of options can be changed mid-session. Currently the only
+ // supported functionality is expanding the list of producer_name_filters()
+ // (or removing the filter entirely) for existing data sources.
+ virtual void ChangeTraceConfig(const TraceConfig&) = 0;
+
+ // Starts all data sources configured in the trace config. This is used only
+ // after calling EnableTracing() with TraceConfig.deferred_start=true.
+ // It's a no-op if called after a regular EnableTracing(), without setting
+ // deferred_start.
+ virtual void StartTracing() = 0;
+
+ virtual void DisableTracing() = 0;
+
+ // Requests all data sources to flush their data immediately and invokes the
+ // passed callback once all of them have acked the flush (in which case
+ // the callback argument |success| will be true) or |timeout_ms| are elapsed
+ // (in which case |success| will be false).
+ // If |timeout_ms| is 0 the TraceConfig's flush_timeout_ms is used, or,
+ // if that one is not set (or is set to 0), kDefaultFlushTimeoutMs (5s) is
+ // used.
+ using FlushCallback = std::function<void(bool /*success*/)>;
+ virtual void Flush(uint32_t timeout_ms, FlushCallback) = 0;
+
+ // Tracing data will be delivered invoking Consumer::OnTraceData().
+ virtual void ReadBuffers() = 0;
+
+ virtual void FreeBuffers() = 0;
+
+ // Will call OnDetach().
+ virtual void Detach(const std::string& key) = 0;
+
+ // Will call OnAttach().
+ virtual void Attach(const std::string& key) = 0;
+
+ // Will call OnTraceStats().
+ virtual void GetTraceStats() = 0;
+
+ enum ObservableEventType : uint32_t {
+ kNone = 0,
+ kDataSourceInstances = 1 << 0
+ };
+
+ // Start or stop observing events of selected types. |enabled_event_types|
+ // specifies the types of events to observe in a bitmask (see
+ // ObservableEventType enum). To disable observing, pass
+ // ObservableEventType::kNone. Will call OnObservableEvents() repeatedly
+ // whenever an event of an enabled ObservableEventType occurs.
+ //
+ // TODO(eseckler): Extend this to support producers & data sources.
+ virtual void ObserveEvents(uint32_t enabled_event_types) = 0;
+}; // class ConsumerEndpoint.
+
// The public API of the tracing Service business logic.
//
// Exposed to:
@@ -57,164 +216,8 @@ class TraceWriter;
// The service business logic in src/core/tracing_service_impl.cc.
class PERFETTO_EXPORT TracingService {
public:
- // The API for the Producer port of the Service.
- // Subclassed by:
- // 1. The tracing_service_impl.cc business logic when returning it in response
- // to the ConnectProducer() method.
- // 2. The transport layer (e.g., src/ipc) when the producer and
- // the service don't talk locally but via some IPC mechanism.
- class PERFETTO_EXPORT ProducerEndpoint {
- public:
- virtual ~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 UnregisterDataSource(const std::string& name) = 0;
-
- // Associate the trace writer with the given |writer_id| with
- // |target_buffer|. The service may use this information to retrieve and
- // copy uncommitted chunks written by the trace writer into its associated
- // buffer, e.g. when a producer process crashes or when a flush is
- // necessary.
- virtual void RegisterTraceWriter(uint32_t writer_id,
- uint32_t target_buffer) = 0;
-
- // Remove the association of the trace writer previously created via
- // RegisterTraceWriter.
- virtual void UnregisterTraceWriter(uint32_t writer_id) = 0;
-
- // Called by the Producer to signal that some pages in the shared memory
- // buffer (shared between Service and Producer) have changed.
- // When the Producer and the Service are hosted in the same process and
- // hence potentially live on the same task runner, This method must call
- // TracingServiceImpl's CommitData synchronously, without any PostTask()s,
- // if on the same thread. This is to avoid a deadlock where the Producer
- // exhausts its SMB and stalls waiting for the service to catch up with
- // reads, but the Service never gets to that because it lives on the same
- // thread.
- using CommitDataCallback = std::function<void()>;
- virtual void CommitData(const CommitDataRequest&,
- CommitDataCallback callback = {}) = 0;
-
- virtual SharedMemory* shared_memory() const = 0;
-
- // Size of shared memory buffer pages. It's always a multiple of 4K.
- // See shared_memory_abi.h
- virtual size_t shared_buffer_page_size_kb() const = 0;
-
- // Creates a trace writer, which allows to create events, handling the
- // underying shared memory buffer and signalling to the Service. This method
- // is thread-safe but the returned object is not. A TraceWriter should be
- // used only from a single thread, or the caller has to handle sequencing
- // via a mutex or equivalent. This method can only be called if
- // TracingService::ConnectProducer was called with |in_process=true|.
- // Args:
- // |target_buffer| is the target buffer ID where the data produced by the
- // writer should be stored by the tracing service. This value is passed
- // upon creation of the data source (StartDataSource()) in the
- // DataSourceConfig.target_buffer().
- virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
- BufferID target_buffer) = 0;
-
- // If TracingService::ConnectProducer is called with |in_process=true|,
- // this returns the producer's SharedMemoryArbiter which can be used
- // to create TraceWriters which is able to directly commit chunks
- // without going through an IPC layer.
- virtual SharedMemoryArbiter* GetInProcessShmemArbiter() = 0;
-
- // Called in response to a Producer::Flush(request_id) call after all data
- // for the flush request has been committed.
- virtual void NotifyFlushComplete(FlushRequestID) = 0;
-
- // Called in response to one or more Producer::StartDataSource(),
- // if the data source registered setting the flag
- // DataSourceDescriptor.will_notify_on_start.
- virtual void NotifyDataSourceStarted(DataSourceInstanceID) = 0;
-
- // Called in response to one or more Producer::StopDataSource(),
- // if the data source registered setting the flag
- // DataSourceDescriptor.will_notify_on_stop.
- virtual void NotifyDataSourceStopped(DataSourceInstanceID) = 0;
-
- // This informs the service to activate any of these triggers if any tracing
- // session was waiting for them.
- virtual void ActivateTriggers(const std::vector<std::string>&) = 0;
- }; // class ProducerEndpoint.
-
- // The API for the Consumer port of the Service.
- // Subclassed by:
- // 1. The tracing_service_impl.cc business logic when returning it in response
- // to
- // the ConnectConsumer() method.
- // 2. The transport layer (e.g., src/ipc) when the consumer and
- // the service don't talk locally but via some IPC mechanism.
- class ConsumerEndpoint {
- public:
- virtual ~ConsumerEndpoint();
-
- // Enables tracing with the given TraceConfig. The ScopedFile argument is
- // used only when TraceConfig.write_into_file == true.
- // If TraceConfig.deferred_start == true data sources are configured via
- // SetupDataSource() but are not started until StartTracing() is called.
- // This is to support pre-initialization and fast triggering of traces.
- // The ScopedFile argument is used only when TraceConfig.write_into_file
- // == true.
- virtual void EnableTracing(const TraceConfig&,
- base::ScopedFile = base::ScopedFile()) = 0;
-
- // Update the trace config of an existing tracing session; only a subset
- // of options can be changed mid-session. Currently the only
- // supported functionality is expanding the list of producer_name_filters()
- // (or removing the filter entirely) for existing data sources.
- virtual void ChangeTraceConfig(const TraceConfig&) = 0;
-
- // Starts all data sources configured in the trace config. This is used only
- // after calling EnableTracing() with TraceConfig.deferred_start=true.
- // It's a no-op if called after a regular EnableTracing(), without setting
- // deferred_start.
- virtual void StartTracing() = 0;
-
- virtual void DisableTracing() = 0;
-
- // Requests all data sources to flush their data immediately and invokes the
- // passed callback once all of them have acked the flush (in which case
- // the callback argument |success| will be true) or |timeout_ms| are elapsed
- // (in which case |success| will be false).
- // If |timeout_ms| is 0 the TraceConfig's flush_timeout_ms is used, or,
- // if that one is not set (or is set to 0), kDefaultFlushTimeoutMs (5s) is
- // used.
- using FlushCallback = std::function<void(bool /*success*/)>;
- virtual void Flush(uint32_t timeout_ms, FlushCallback) = 0;
-
- // Tracing data will be delivered invoking Consumer::OnTraceData().
- virtual void ReadBuffers() = 0;
-
- virtual void FreeBuffers() = 0;
-
- // Will call OnDetach().
- virtual void Detach(const std::string& key) = 0;
-
- // Will call OnAttach().
- virtual void Attach(const std::string& key) = 0;
-
- // Will call OnTraceStats().
- virtual void GetTraceStats() = 0;
-
- enum ObservableEventType : uint32_t {
- kNone = 0,
- kDataSourceInstances = 1 << 0
- };
-
- // Start or stop observing events of selected types. |enabled_event_types|
- // specifies the types of events to observe in a bitmask (see
- // ObservableEventType enum). To disable observing, pass
- // ObservableEventType::kNone. Will call OnObservableEvents() repeatedly
- // whenever an event of an enabled ObservableEventType occurs.
- //
- // TODO(eseckler): Extend this to support producers & data sources.
- virtual void ObserveEvents(uint32_t enabled_event_types) = 0;
- }; // class ConsumerEndpoint.
+ using ProducerEndpoint = perfetto::ProducerEndpoint;
+ using ConsumerEndpoint = perfetto::ConsumerEndpoint;
// Implemented in src/core/tracing_service_impl.cc .
static std::unique_ptr<TracingService> CreateInstance(
diff --git a/perfetto.rc b/perfetto.rc
index 40e5f7534..8d077131e 100644
--- a/perfetto.rc
+++ b/perfetto.rc
@@ -35,10 +35,10 @@ service traced_probes /system/bin/traced_probes
file /dev/kmsg w
capabilities DAC_READ_SEARCH
-on property:sys.traced.enable_override=1
+on property:persist.device_config.global_settings.sys_traced=1
setprop persist.traced.enable 1
-on property:sys.traced.enable_override=0
+on property:persist.device_config.global_settings.sys_traced=0
setprop persist.traced.enable 0
on property:debug.atrace.user_initiated=1
diff --git a/protos/BUILD b/protos/BUILD
index ed2ce1fc3..bbcdc0f0c 100644
--- a/protos/BUILD
+++ b/protos/BUILD
@@ -29,6 +29,7 @@ proto_library(
srcs = [
"perfetto/common/android_log_constants.proto",
"perfetto/common/commit_data_request.proto",
+ "perfetto/common/descriptor.proto",
"perfetto/common/observable_events.proto",
"perfetto/common/sys_stats_counters.proto",
"perfetto/common/trace_stats.proto",
@@ -58,6 +59,7 @@ proto_library(
srcs = [
"perfetto/common/android_log_constants.proto",
"perfetto/common/commit_data_request.proto",
+ "perfetto/common/descriptor.proto",
"perfetto/common/observable_events.proto",
"perfetto/common/sys_stats_counters.proto",
"perfetto/common/trace_stats.proto",
diff --git a/protos/perfetto/common/BUILD.gn b/protos/perfetto/common/BUILD.gn
index a67b42d56..36a9b20e8 100644
--- a/protos/perfetto/common/BUILD.gn
+++ b/protos/perfetto/common/BUILD.gn
@@ -17,8 +17,9 @@ import("../../../gn/proto_library.gni")
import("../../../gn/protozero_library.gni")
common_sources = [
- "commit_data_request.proto",
"android_log_constants.proto",
+ "commit_data_request.proto",
+ "descriptor.proto",
"observable_events.proto",
"sys_stats_counters.proto",
"trace_stats.proto",
diff --git a/src/perfetto_cmd/descriptor.proto b/protos/perfetto/common/descriptor.proto
index be0fff5c5..be0fff5c5 100644
--- a/src/perfetto_cmd/descriptor.proto
+++ b/protos/perfetto/common/descriptor.proto
diff --git a/protos/perfetto/config/data_source_descriptor.proto b/protos/perfetto/config/data_source_descriptor.proto
index 6414f5139..28e59d748 100644
--- a/protos/perfetto/config/data_source_descriptor.proto
+++ b/protos/perfetto/config/data_source_descriptor.proto
@@ -38,6 +38,11 @@ message DataSourceDescriptor {
// Android P in March 2019 and is not supported on older versions.
optional bool will_notify_on_start = 3;
+ // If true, opt into receiving the ClearIncrementalState() IPC. This should be
+ // set if the data source writes packets that refer to previous trace
+ // contents, and knows how to stop referring to the already-emitted data.
+ optional bool handles_incremental_state_clear = 4;
+
// TODO: this should have a structure to enable reflection of the proto
// fields emitted (see go/perfetto-logging).
}
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index c64bd112e..daa6b8b93 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -489,7 +489,7 @@ message TestConfig {
// Begin of protos/perfetto/config/trace_config.proto
-// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
+// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos
// to reflect changes in the corresponding C++ headers.
// The overall config that is used when starting a new tracing session through
@@ -497,7 +497,7 @@ message TestConfig {
// It contains the general config for the logging buffer(s) and the configs for
// all the data source being enabled.
//
-// Next id: 20.
+// Next id: 23.
message TraceConfig {
message BufferConfig {
optional uint32 size_kb = 1;
@@ -541,6 +541,18 @@ message TraceConfig {
}
repeated DataSource data_sources = 2;
+ // Config for builtin trace packets emitted by perfetto like trace stats,
+ // system info, etc.
+ message BuiltinDataSource {
+ // Disable emitting clock timestamps into the trace.
+ optional bool disable_clock_snapshotting = 1;
+
+ optional bool disable_trace_config = 2;
+
+ optional bool disable_system_info = 3;
+ }
+ optional BuiltinDataSource builtin_data_sources = 20;
+
// If specified, the trace will be stopped |duration_ms| after starting.
// However in case of traces with triggers, see
// TriggerConfig.trigger_timeout_ms instead.
@@ -635,8 +647,7 @@ message TraceConfig {
// Default 5s.
optional uint32 flush_timeout_ms = 14;
- // Disable emitting clock timestamps into the trace.
- optional bool disable_clock_snapshotting = 15;
+ reserved 15; // |disable_clock_snapshotting| moved.
// Android-only. If set, sends an intent to the Traceur system app when the
// trace ends to notify it about the trace readiness.
@@ -704,11 +715,37 @@ message TraceConfig {
// that were previous configured to use a TriggerConfig.
repeated string activate_triggers = 18;
+ // Configuration for trace contents that reference earlier trace data. For
+ // example, a data source might intern strings, and emit packets containing
+ // {interned id : string} pairs. Future packets from that data source can then
+ // use the interned ids instead of duplicating the raw string contents. The
+ // trace parser will then need to use that interning table to fully interpret
+ // the rest of the trace.
+ message IncrementalStateConfig {
+ // If nonzero, notify eligible data sources to clear their incremental state
+ // periodically, with the given period. The notification is sent only to
+ // data sources that have |handles_incremental_state_clear| set in their
+ // DataSourceDescriptor. The notification requests that the data source
+ // stops referring to past trace contents. This is particularly useful when
+ // tracing in ring buffer mode, where it is not exceptional to overwrite old
+ // trace data.
+ //
+ // Warning: this time-based global clearing is likely to be removed in the
+ // future, to be replaced with a smarter way of sending the notifications
+ // only when necessary.
+ optional uint32 clear_period_ms = 1;
+ }
+ optional IncrementalStateConfig incremental_state_config = 21;
+
// Additional guardrail used by the Perfetto command line client.
// On user builds when --dropbox is set perfetto will refuse to trace unless
// this is also set.
// Added in Q.
optional bool allow_user_build_tracing = 19;
+
+ // If set the tracing service will ensure there is at most one tracing session
+ // with this key.
+ optional string unique_session_name = 22;
}
// End of protos/perfetto/config/trace_config.proto
diff --git a/protos/perfetto/config/trace_config.proto b/protos/perfetto/config/trace_config.proto
index a2a6fa699..802836e9e 100644
--- a/protos/perfetto/config/trace_config.proto
+++ b/protos/perfetto/config/trace_config.proto
@@ -21,7 +21,7 @@ import "perfetto/config/data_source_config.proto";
package perfetto.protos;
-// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
+// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos
// to reflect changes in the corresponding C++ headers.
// The overall config that is used when starting a new tracing session through
@@ -29,7 +29,7 @@ package perfetto.protos;
// It contains the general config for the logging buffer(s) and the configs for
// all the data source being enabled.
//
-// Next id: 20.
+// Next id: 23.
message TraceConfig {
message BufferConfig {
optional uint32 size_kb = 1;
@@ -73,6 +73,18 @@ message TraceConfig {
}
repeated DataSource data_sources = 2;
+ // Config for builtin trace packets emitted by perfetto like trace stats,
+ // system info, etc.
+ message BuiltinDataSource {
+ // Disable emitting clock timestamps into the trace.
+ optional bool disable_clock_snapshotting = 1;
+
+ optional bool disable_trace_config = 2;
+
+ optional bool disable_system_info = 3;
+ }
+ optional BuiltinDataSource builtin_data_sources = 20;
+
// If specified, the trace will be stopped |duration_ms| after starting.
// However in case of traces with triggers, see
// TriggerConfig.trigger_timeout_ms instead.
@@ -167,8 +179,7 @@ message TraceConfig {
// Default 5s.
optional uint32 flush_timeout_ms = 14;
- // Disable emitting clock timestamps into the trace.
- optional bool disable_clock_snapshotting = 15;
+ reserved 15; // |disable_clock_snapshotting| moved.
// Android-only. If set, sends an intent to the Traceur system app when the
// trace ends to notify it about the trace readiness.
@@ -236,9 +247,35 @@ message TraceConfig {
// that were previous configured to use a TriggerConfig.
repeated string activate_triggers = 18;
+ // Configuration for trace contents that reference earlier trace data. For
+ // example, a data source might intern strings, and emit packets containing
+ // {interned id : string} pairs. Future packets from that data source can then
+ // use the interned ids instead of duplicating the raw string contents. The
+ // trace parser will then need to use that interning table to fully interpret
+ // the rest of the trace.
+ message IncrementalStateConfig {
+ // If nonzero, notify eligible data sources to clear their incremental state
+ // periodically, with the given period. The notification is sent only to
+ // data sources that have |handles_incremental_state_clear| set in their
+ // DataSourceDescriptor. The notification requests that the data source
+ // stops referring to past trace contents. This is particularly useful when
+ // tracing in ring buffer mode, where it is not exceptional to overwrite old
+ // trace data.
+ //
+ // Warning: this time-based global clearing is likely to be removed in the
+ // future, to be replaced with a smarter way of sending the notifications
+ // only when necessary.
+ optional uint32 clear_period_ms = 1;
+ }
+ optional IncrementalStateConfig incremental_state_config = 21;
+
// Additional guardrail used by the Perfetto command line client.
// On user builds when --dropbox is set perfetto will refuse to trace unless
// this is also set.
// Added in Q.
optional bool allow_user_build_tracing = 19;
+
+ // If set the tracing service will ensure there is at most one tracing session
+ // with this key.
+ optional string unique_session_name = 22;
}
diff --git a/protos/perfetto/ipc/producer_port.proto b/protos/perfetto/ipc/producer_port.proto
index 797833cb1..24efc27bd 100644
--- a/protos/perfetto/ipc/producer_port.proto
+++ b/protos/perfetto/ipc/producer_port.proto
@@ -213,7 +213,18 @@ message GetAsyncCommandResponse {
optional uint64 request_id = 2;
}
- // Next id: 7.
+ // Instructs the given data sources to stop referring to any trace contents
+ // emitted so far. Sent only to active data sources that set
+ // |handles_incremental_state_clear| in their DataSourceDescriptor.
+ //
+ // Added to perfetto tree in May 2019.
+ message ClearIncrementalState {
+ // The instance id (i.e. StartDataSource.new_instance_id) of the data
+ // sources that should clear their incremental state.
+ repeated uint64 data_source_ids = 1;
+ }
+
+ // Next id: 8.
oneof cmd {
SetupTracing setup_tracing = 3;
SetupDataSource setup_data_source = 6;
@@ -221,5 +232,6 @@ message GetAsyncCommandResponse {
StopDataSource stop_data_source = 2;
// id == 4 was teardown_tracing, never implemented.
Flush flush = 5;
+ ClearIncrementalState clear_incremental_state = 7;
}
}
diff --git a/protos/perfetto/trace/chrome/BUILD.gn b/protos/perfetto/trace/chrome/BUILD.gn
index f63757379..33297f09e 100644
--- a/protos/perfetto/trace/chrome/BUILD.gn
+++ b/protos/perfetto/trace/chrome/BUILD.gn
@@ -15,7 +15,9 @@
import("../../../../gn/perfetto.gni")
import("../../../../gn/protozero_library.gni")
-chrome_proto_names = [ "chrome_trace_event.proto" ]
+chrome_proto_names = [
+ "chrome_trace_event.proto",
+]
minimal_chrome_proto_names = [ "chrome_trace_packet.proto" ]
proto_library("lite") {
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index f63998952..d57288446 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -2846,7 +2846,7 @@ message Trace {
// TracePacket(s).
//
// Next reserved id: 13 (up to 15).
-// Next id: 47.
+// Next id: 49.
message TracePacket {
// TODO(primiano): in future we should add a timestamp_clock_domain field to
// allow mixing timestamps from different clock domains.
@@ -2887,7 +2887,12 @@ message TracePacket {
bytes synchronization_marker = 36;
// This field is only used for testing.
- // removed field with id 268435455 // 2^28 - 1, max field id for protos.
+ // In previous versions of this proto this field had the id 268435455
+ // This caused many problems:
+ // - protozero decoder does not handle field ids larger than 999.
+ // - old versions of protoc produce Java bindings with syntax errors when
+ // the field id is large enough.
+ // removed field with id 900
}
// Trusted user id of the producer which generated this packet. Keep in sync
@@ -3544,7 +3549,7 @@ message TestConfig {
// Begin of protos/perfetto/config/trace_config.proto
-// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
+// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos
// to reflect changes in the corresponding C++ headers.
// The overall config that is used when starting a new tracing session through
@@ -3552,7 +3557,7 @@ message TestConfig {
// It contains the general config for the logging buffer(s) and the configs for
// all the data source being enabled.
//
-// Next id: 20.
+// Next id: 23.
message TraceConfig {
message BufferConfig {
optional uint32 size_kb = 1;
@@ -3596,6 +3601,18 @@ message TraceConfig {
}
repeated DataSource data_sources = 2;
+ // Config for builtin trace packets emitted by perfetto like trace stats,
+ // system info, etc.
+ message BuiltinDataSource {
+ // Disable emitting clock timestamps into the trace.
+ optional bool disable_clock_snapshotting = 1;
+
+ optional bool disable_trace_config = 2;
+
+ optional bool disable_system_info = 3;
+ }
+ optional BuiltinDataSource builtin_data_sources = 20;
+
// If specified, the trace will be stopped |duration_ms| after starting.
// However in case of traces with triggers, see
// TriggerConfig.trigger_timeout_ms instead.
@@ -3690,8 +3707,7 @@ message TraceConfig {
// Default 5s.
optional uint32 flush_timeout_ms = 14;
- // Disable emitting clock timestamps into the trace.
- optional bool disable_clock_snapshotting = 15;
+ reserved 15; // |disable_clock_snapshotting| moved.
// Android-only. If set, sends an intent to the Traceur system app when the
// trace ends to notify it about the trace readiness.
@@ -3759,11 +3775,37 @@ message TraceConfig {
// that were previous configured to use a TriggerConfig.
repeated string activate_triggers = 18;
+ // Configuration for trace contents that reference earlier trace data. For
+ // example, a data source might intern strings, and emit packets containing
+ // {interned id : string} pairs. Future packets from that data source can then
+ // use the interned ids instead of duplicating the raw string contents. The
+ // trace parser will then need to use that interning table to fully interpret
+ // the rest of the trace.
+ message IncrementalStateConfig {
+ // If nonzero, notify eligible data sources to clear their incremental state
+ // periodically, with the given period. The notification is sent only to
+ // data sources that have |handles_incremental_state_clear| set in their
+ // DataSourceDescriptor. The notification requests that the data source
+ // stops referring to past trace contents. This is particularly useful when
+ // tracing in ring buffer mode, where it is not exceptional to overwrite old
+ // trace data.
+ //
+ // Warning: this time-based global clearing is likely to be removed in the
+ // future, to be replaced with a smarter way of sending the notifications
+ // only when necessary.
+ optional uint32 clear_period_ms = 1;
+ }
+ optional IncrementalStateConfig incremental_state_config = 21;
+
// Additional guardrail used by the Perfetto command line client.
// On user builds when --dropbox is set perfetto will refuse to trace unless
// this is also set.
// Added in Q.
optional bool allow_user_build_tracing = 19;
+
+ // If set the tracing service will ensure there is at most one tracing session
+ // with this key.
+ optional string unique_session_name = 22;
}
// End of protos/perfetto/config/trace_config.proto
diff --git a/protos/perfetto/trace/trace_packet.proto b/protos/perfetto/trace/trace_packet.proto
index 0a4a497bf..1a29ea6b4 100644
--- a/protos/perfetto/trace/trace_packet.proto
+++ b/protos/perfetto/trace/trace_packet.proto
@@ -46,7 +46,7 @@ package perfetto.protos;
// TracePacket(s).
//
// Next reserved id: 13 (up to 15).
-// Next id: 47.
+// Next id: 49.
message TracePacket {
// TODO(primiano): in future we should add a timestamp_clock_domain field to
// allow mixing timestamps from different clock domains.
@@ -87,7 +87,12 @@ message TracePacket {
bytes synchronization_marker = 36;
// This field is only used for testing.
- TestEvent for_testing = 268435455; // 2^28 - 1, max field id for protos.
+ // In previous versions of this proto this field had the id 268435455
+ // This caused many problems:
+ // - protozero decoder does not handle field ids larger than 999.
+ // - old versions of protoc produce Java bindings with syntax errors when
+ // the field id is large enough.
+ TestEvent for_testing = 900;
}
// Trusted user id of the producer which generated this packet. Keep in sync
diff --git a/src/base/metatrace.cc b/src/base/metatrace.cc
index baae16457..99b787f4a 100644
--- a/src/base/metatrace.cc
+++ b/src/base/metatrace.cc
@@ -40,6 +40,8 @@ int MaybeOpenTraceFile() {
}
} // namespace
+constexpr uint32_t MetaTrace::kMainThreadCpu;
+
void MetaTrace::WriteEvent(char type, const char* evt_name, size_t cpu) {
int fd = MaybeOpenTraceFile();
if (fd == -1)
diff --git a/src/perfetto_cmd/BUILD.gn b/src/perfetto_cmd/BUILD.gn
index 2a5408ba2..b4ec76ceb 100644
--- a/src/perfetto_cmd/BUILD.gn
+++ b/src/perfetto_cmd/BUILD.gn
@@ -24,6 +24,7 @@ source_set("perfetto_cmd") {
":trigger_producer",
"../../buildtools:protobuf_lite",
"../../gn:default_deps",
+ "../../protos/perfetto/common:lite",
"../../protos/perfetto/config:lite",
"../base",
"../protozero",
@@ -84,7 +85,6 @@ proto_library("protos") {
generate_python = false
deps = []
sources = [
- "descriptor.proto",
"perfetto_cmd_state.proto",
]
proto_in_dir = perfetto_root_path
diff --git a/src/perfetto_cmd/config.cc b/src/perfetto_cmd/config.cc
index 7e23df59c..5b881def7 100644
--- a/src/perfetto_cmd/config.cc
+++ b/src/perfetto_cmd/config.cc
@@ -22,7 +22,6 @@
namespace perfetto {
namespace {
-using protos::TraceConfig;
using ValueUnit = std::pair<uint64_t, std::string>;
using UnitMultipler = std::pair<const char*, uint64_t>;
@@ -84,7 +83,7 @@ bool ConvertSizeToKb(const std::string& arg, uint64_t* out) {
} // namespace
bool CreateConfigFromOptions(const ConfigOptions& options,
- TraceConfig* config) {
+ protos::TraceConfig* config) {
uint64_t duration_ms = 0;
if (!ConvertTimeToMs(options.time, &duration_ms)) {
PERFETTO_ELOG("--time argument is invalid");
diff --git a/src/perfetto_cmd/pbtxt_to_pb.cc b/src/perfetto_cmd/pbtxt_to_pb.cc
index 4dc051894..cc123a93c 100644
--- a/src/perfetto_cmd/pbtxt_to_pb.cc
+++ b/src/perfetto_cmd/pbtxt_to_pb.cc
@@ -22,12 +22,12 @@
#include "src/perfetto_cmd/pbtxt_to_pb.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
-#include "src/perfetto_cmd/descriptor.pb.h"
#include "perfetto/base/file_utils.h"
#include "perfetto/base/logging.h"
#include "perfetto/base/string_view.h"
#include "perfetto/base/utils.h"
+#include "perfetto/common/descriptor.pb.h"
#include "perfetto/protozero/message.h"
#include "perfetto/protozero/message_handle.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
@@ -661,17 +661,12 @@ std::vector<uint8_t> PbtxtToPb(const std::string& input,
const DescriptorProto* descriptor = name_to_descriptor[kConfigProtoName];
PERFETTO_CHECK(descriptor);
- protozero::ScatteredHeapBuffer stream_delegate(base::kPageSize);
- protozero::ScatteredStreamWriter stream(&stream_delegate);
- stream_delegate.set_writer(&stream);
-
- protozero::Message message;
- message.Reset(&stream);
- ParserDelegate delegate(descriptor, &message, reporter,
+ protozero::HeapBuffered<protozero::Message> message;
+ ParserDelegate delegate(descriptor, message.get(), reporter,
std::move(name_to_descriptor),
std::move(name_to_enum));
Parse(input, &delegate);
- return stream_delegate.StitchSlices();
+ return message.SerializeAsArray();
}
} // namespace perfetto
diff --git a/src/perfetto_cmd/perfetto_cmd.cc b/src/perfetto_cmd/perfetto_cmd.cc
index 6648c43a5..aa3feb955 100644
--- a/src/perfetto_cmd/perfetto_cmd.cc
+++ b/src/perfetto_cmd/perfetto_cmd.cc
@@ -517,6 +517,13 @@ int PerfettoCmd::Main(int argc, char** argv) {
args.max_upload_bytes_override =
trace_config_->guardrail_overrides().max_upload_per_day_bytes();
#endif
+
+ if ((trace_config_->duration_ms() == 0) && args.is_dropbox &&
+ !args.ignore_guardrails) {
+ PERFETTO_ELOG("Can't trace indefinitely when uploading via Dropbox.");
+ return 1;
+ }
+
if (!limiter.ShouldTrace(args))
return 1;
diff --git a/src/perfetto_cmd/perfetto_config.descriptor.h b/src/perfetto_cmd/perfetto_config.descriptor.h
index c49b14fb9..e0dfe44fb 100644
--- a/src/perfetto_cmd/perfetto_config.descriptor.h
+++ b/src/perfetto_cmd/perfetto_config.descriptor.h
@@ -12,15 +12,15 @@
// SHA1(tools/gen_binary_descriptors)
// e329b1e1e964417db57f83d8ecf081e041923e78
// SHA1(protos/perfetto/config/perfetto_config.proto)
-// 8132339dc93464524410353c402ee3225d79b74a
+// e0639d910f73cc9395ffafe5c153ac28982e742f
// This is the proto PerfettoConfig encoded as a ProtoFileDescriptor to allow
// for reflection without libprotobuf full/non-lite protos.
namespace perfetto {
-constexpr std::array<uint8_t, 10710> kPerfettoConfigDescriptor{
- {0x0a, 0xd3, 0x53, 0x0a, 0x25, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
+constexpr std::array<uint8_t, 11159> kPerfettoConfigDescriptor{
+ {0x0a, 0x94, 0x57, 0x0a, 0x25, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
0x6f, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x70, 0x65, 0x72,
0x66, 0x65, 0x74, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x70, 0x65, 0x72, 0x66,
@@ -352,8 +352,8 @@ constexpr std::array<uint8_t, 10710> kPerfettoConfigDescriptor{
0x52, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e,
0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62,
0x79, 0x74, 0x65, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a,
- 0x66, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xdf,
- 0x12, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66,
+ 0x66, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xa0,
+ 0x16, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x12, 0x43, 0x0a, 0x07, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72,
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x65,
0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
@@ -366,70 +366,73 @@ constexpr std::array<uint8_t, 10710> kPerfettoConfigDescriptor{
0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x52, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72,
- 0x63, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x75, 0x72, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d,
- 0x52, 0x0a, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x73,
- 0x12, 0x36, 0x0a, 0x17, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x65,
- 0x78, 0x74, 0x72, 0x61, 0x5f, 0x67, 0x75, 0x61, 0x72, 0x64, 0x72, 0x61,
- 0x69, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x65,
- 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x72, 0x61, 0x47, 0x75,
- 0x61, 0x72, 0x64, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x57, 0x0a, 0x0d,
- 0x6c, 0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x6d, 0x6f, 0x64,
- 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x70, 0x65,
+ 0x63, 0x65, 0x73, 0x12, 0x60, 0x0a, 0x14, 0x62, 0x75, 0x69, 0x6c, 0x74,
+ 0x69, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x6f, 0x75, 0x72,
+ 0x63, 0x65, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e,
+ 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x44,
+ 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x12, 0x62,
+ 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f,
+ 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x75, 0x72,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x0d, 0x52, 0x0a, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x4d, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65,
+ 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x67, 0x75, 0x61, 0x72, 0x64,
+ 0x72, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x15, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x72, 0x61,
+ 0x47, 0x75, 0x61, 0x72, 0x64, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x57,
+ 0x0a, 0x0d, 0x6c, 0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x6d,
+ 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e,
+ 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x2e, 0x4c, 0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e,
+ 0x4d, 0x6f, 0x64, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x52, 0x0c, 0x6c, 0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x4d,
+ 0x6f, 0x64, 0x65, 0x12, 0x49, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75,
+ 0x63, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b,
+ 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65,
+ 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x09, 0x70, 0x72, 0x6f,
+ 0x64, 0x75, 0x63, 0x65, 0x72, 0x73, 0x12, 0x54, 0x0a, 0x0f, 0x73, 0x74,
+ 0x61, 0x74, 0x73, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+ 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65,
0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x2e, 0x4c, 0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x6f,
- 0x64, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
- 0x0c, 0x6c, 0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x6f, 0x64,
- 0x65, 0x12, 0x49, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65,
- 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70,
- 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66,
- 0x69, 0x67, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x43,
- 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75,
- 0x63, 0x65, 0x72, 0x73, 0x12, 0x54, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x74,
- 0x73, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18,
- 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66,
+ 0x67, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x64, 0x4d, 0x65, 0x74, 0x61,
+ 0x64, 0x61, 0x74, 0x61, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64,
+ 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0f,
+ 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x6f, 0x5f, 0x66,
+ 0x69, 0x6c, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x77,
+ 0x72, 0x69, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x6f, 0x46, 0x69, 0x6c, 0x65,
+ 0x12, 0x2f, 0x0a, 0x14, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x77, 0x72, 0x69,
+ 0x74, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73,
+ 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x66, 0x69, 0x6c, 0x65,
+ 0x57, 0x72, 0x69, 0x74, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x4d,
+ 0x73, 0x12, 0x2d, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x69, 0x6c,
+ 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73,
+ 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x46,
+ 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73,
+ 0x12, 0x60, 0x0a, 0x13, 0x67, 0x75, 0x61, 0x72, 0x64, 0x72, 0x61, 0x69,
+ 0x6c, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x18,
+ 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, 0x65, 0x72, 0x66,
0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
- 0x53, 0x74, 0x61, 0x74, 0x73, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
- 0x74, 0x61, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x4d, 0x65,
- 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0f, 0x77, 0x72,
- 0x69, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x6f, 0x5f, 0x66, 0x69, 0x6c,
- 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x77, 0x72, 0x69,
- 0x74, 0x65, 0x49, 0x6e, 0x74, 0x6f, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x2f,
- 0x0a, 0x14, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65,
- 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x18, 0x09,
- 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x66, 0x69, 0x6c, 0x65, 0x57, 0x72,
- 0x69, 0x74, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x4d, 0x73, 0x12,
- 0x2d, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f,
- 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x0a,
- 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x46, 0x69, 0x6c,
- 0x65, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x60,
- 0x0a, 0x13, 0x67, 0x75, 0x61, 0x72, 0x64, 0x72, 0x61, 0x69, 0x6c, 0x5f,
- 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x18, 0x0b, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
- 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72,
- 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x47, 0x75,
- 0x61, 0x72, 0x64, 0x72, 0x61, 0x69, 0x6c, 0x4f, 0x76, 0x65, 0x72, 0x72,
- 0x69, 0x64, 0x65, 0x73, 0x52, 0x12, 0x67, 0x75, 0x61, 0x72, 0x64, 0x72,
- 0x61, 0x69, 0x6c, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73,
- 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64,
- 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08,
- 0x52, 0x0d, 0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x53, 0x74,
- 0x61, 0x72, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x66, 0x6c, 0x75, 0x73, 0x68,
- 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x18, 0x0d,
- 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x50,
- 0x65, 0x72, 0x69, 0x6f, 0x64, 0x4d, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x66,
- 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74,
- 0x5f, 0x6d, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x66,
- 0x6c, 0x75, 0x73, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d,
- 0x73, 0x12, 0x3c, 0x0a, 0x1a, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
- 0x5f, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73,
- 0x68, 0x6f, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28,
- 0x08, 0x52, 0x18, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6c,
- 0x6f, 0x63, 0x6b, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x74,
- 0x69, 0x6e, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66,
+ 0x47, 0x75, 0x61, 0x72, 0x64, 0x72, 0x61, 0x69, 0x6c, 0x4f, 0x76, 0x65,
+ 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x52, 0x12, 0x67, 0x75, 0x61, 0x72,
+ 0x64, 0x72, 0x61, 0x69, 0x6c, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64,
+ 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x65, 0x66, 0x65, 0x72, 0x72,
+ 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x0c, 0x20, 0x01,
+ 0x28, 0x08, 0x52, 0x0d, 0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64,
+ 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x66, 0x6c, 0x75,
+ 0x73, 0x68, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73,
+ 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x66, 0x6c, 0x75, 0x73,
+ 0x68, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x4d, 0x73, 0x12, 0x28, 0x0a,
+ 0x10, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f,
+ 0x75, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0d, 0x52,
+ 0x0e, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75,
+ 0x74, 0x4d, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66,
0x79, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x75, 0x72, 0x18, 0x10, 0x20,
0x01, 0x28, 0x08, 0x52, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x54,
0x72, 0x61, 0x63, 0x65, 0x75, 0x72, 0x12, 0x51, 0x0a, 0x0e, 0x74, 0x72,
@@ -443,476 +446,510 @@ constexpr std::array<uint8_t, 10710> kPerfettoConfigDescriptor{
0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65,
0x72, 0x73, 0x18, 0x12, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x63,
0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65,
- 0x72, 0x73, 0x12, 0x37, 0x0a, 0x18, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f,
- 0x75, 0x73, 0x65, 0x72, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74,
- 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08,
- 0x52, 0x15, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x55, 0x73, 0x65, 0x72, 0x42,
- 0x75, 0x69, 0x6c, 0x64, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x1a,
- 0xc7, 0x01, 0x0a, 0x0c, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x43, 0x6f,
- 0x6e, 0x66, 0x69, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x69, 0x7a, 0x65,
- 0x5f, 0x6b, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73,
- 0x69, 0x7a, 0x65, 0x4b, 0x62, 0x12, 0x55, 0x0a, 0x0b, 0x66, 0x69, 0x6c,
- 0x6c, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01,
- 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
- 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61,
- 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x42, 0x75, 0x66,
- 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x46, 0x69,
- 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0a, 0x66, 0x69,
- 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x3b, 0x0a, 0x0a,
- 0x46, 0x69, 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x0f,
- 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
- 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x49, 0x4e, 0x47, 0x5f,
- 0x42, 0x55, 0x46, 0x46, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07,
- 0x44, 0x49, 0x53, 0x43, 0x41, 0x52, 0x44, 0x10, 0x02, 0x4a, 0x04, 0x08,
- 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x1a, 0x79, 0x0a,
- 0x0a, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12,
- 0x39, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
- 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x44, 0x61,
- 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66,
- 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30,
- 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x5f, 0x6e,
- 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02,
- 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63,
- 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72,
- 0x1a, 0x77, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72,
- 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72,
- 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x64, 0x75,
- 0x63, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0b, 0x73,
- 0x68, 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x6b, 0x62, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x73, 0x68, 0x6d, 0x53, 0x69, 0x7a,
- 0x65, 0x4b, 0x62, 0x12, 0x20, 0x0a, 0x0c, 0x70, 0x61, 0x67, 0x65, 0x5f,
- 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x6b, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x0d, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x4b,
- 0x62, 0x1a, 0xe4, 0x01, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x64,
- 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2e, 0x0a, 0x13,
- 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61,
- 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x03, 0x52, 0x11, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e,
- 0x67, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x15,
- 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x63,
- 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x05, 0x52, 0x13, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72,
- 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x55, 0x69, 0x64,
- 0x12, 0x30, 0x0a, 0x14, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69,
- 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x74, 0x72, 0x69, 0x67,
- 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
- 0x49, 0x64, 0x12, 0x3c, 0x0a, 0x1a, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65,
- 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
- 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01,
- 0x28, 0x03, 0x52, 0x18, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69,
- 0x6e, 0x67, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
- 0x6f, 0x6e, 0x49, 0x64, 0x1a, 0x4c, 0x0a, 0x12, 0x47, 0x75, 0x61, 0x72,
- 0x64, 0x72, 0x61, 0x69, 0x6c, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64,
- 0x65, 0x73, 0x12, 0x36, 0x0a, 0x18, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70,
- 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x79,
- 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
- 0x52, 0x14, 0x6d, 0x61, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x50,
- 0x65, 0x72, 0x44, 0x61, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0xa0,
- 0x03, 0x0a, 0x0d, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f,
- 0x6e, 0x66, 0x69, 0x67, 0x12, 0x59, 0x0a, 0x0c, 0x74, 0x72, 0x69, 0x67,
- 0x67, 0x65, 0x72, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
- 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61,
- 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x72, 0x69,
- 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54,
- 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0b,
- 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x12,
- 0x4e, 0x0a, 0x08, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x18,
- 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x70, 0x65, 0x72, 0x66,
+ 0x72, 0x73, 0x12, 0x6d, 0x0a, 0x18, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d,
+ 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f,
+ 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x33, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65,
+ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x49, 0x6e, 0x63, 0x72, 0x65,
+ 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x16, 0x69, 0x6e, 0x63, 0x72, 0x65,
+ 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x37, 0x0a, 0x18, 0x61, 0x6c, 0x6c,
+ 0x6f, 0x77, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x62, 0x75, 0x69, 0x6c,
+ 0x64, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x13, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x15, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x55, 0x73,
+ 0x65, 0x72, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x54, 0x72, 0x61, 0x63, 0x69,
+ 0x6e, 0x67, 0x12, 0x2e, 0x0a, 0x13, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65,
+ 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d,
+ 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x75, 0x6e, 0x69,
+ 0x71, 0x75, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x61,
+ 0x6d, 0x65, 0x1a, 0xc7, 0x01, 0x0a, 0x0c, 0x42, 0x75, 0x66, 0x66, 0x65,
+ 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x73,
+ 0x69, 0x7a, 0x65, 0x5f, 0x6b, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
+ 0x52, 0x06, 0x73, 0x69, 0x7a, 0x65, 0x4b, 0x62, 0x12, 0x55, 0x0a, 0x0b,
+ 0x66, 0x69, 0x6c, 0x6c, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18,
+ 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x70, 0x65, 0x72, 0x66,
0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
- 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x08, 0x74,
- 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x74,
- 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f,
- 0x75, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52,
- 0x10, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65,
- 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x1a, 0x71, 0x0a, 0x07, 0x54, 0x72, 0x69,
- 0x67, 0x67, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
- 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72,
- 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x64, 0x75,
- 0x63, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x67, 0x65, 0x78,
- 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x64, 0x65, 0x6c,
- 0x61, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52,
- 0x0b, 0x73, 0x74, 0x6f, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73,
- 0x22, 0x43, 0x0a, 0x0b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4d,
- 0x6f, 0x64, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45,
- 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d,
- 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x54, 0x52, 0x41, 0x43, 0x49, 0x4e,
- 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x4f, 0x50, 0x5f,
- 0x54, 0x52, 0x41, 0x43, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x22, 0x55, 0x0a,
- 0x15, 0x4c, 0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x6f, 0x64,
- 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16,
- 0x0a, 0x12, 0x4c, 0x4f, 0x43, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x55,
- 0x4e, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12,
- 0x0a, 0x0e, 0x4c, 0x4f, 0x43, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x43,
- 0x4c, 0x45, 0x41, 0x52, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x4f,
- 0x43, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x10, 0x02,
- 0x22, 0xe4, 0x03, 0x0a, 0x0f, 0x48, 0x65, 0x61, 0x70, 0x70, 0x72, 0x6f,
- 0x66, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a, 0x17,
- 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x74,
- 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x15, 0x73, 0x61, 0x6d, 0x70, 0x6c,
- 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x42,
- 0x79, 0x74, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x63,
- 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6d, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18,
- 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65,
- 0x73, 0x73, 0x43, 0x6d, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x10, 0x0a,
- 0x03, 0x70, 0x69, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x04, 0x52, 0x03,
- 0x70, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x05,
- 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x2c, 0x0a,
- 0x12, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c,
- 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x07, 0x20, 0x03, 0x28,
- 0x09, 0x52, 0x10, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x79, 0x6d, 0x62, 0x6f,
- 0x6c, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x6b, 0x0a, 0x16, 0x63,
- 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x64, 0x75,
- 0x6d, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
- 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65,
+ 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x2e, 0x46, 0x69, 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52,
+ 0x0a, 0x66, 0x69, 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22,
+ 0x3b, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63,
+ 0x79, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49,
+ 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x49,
+ 0x4e, 0x47, 0x5f, 0x42, 0x55, 0x46, 0x46, 0x45, 0x52, 0x10, 0x01, 0x12,
+ 0x0b, 0x0a, 0x07, 0x44, 0x49, 0x53, 0x43, 0x41, 0x52, 0x44, 0x10, 0x02,
+ 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04,
+ 0x1a, 0x79, 0x0a, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72,
+ 0x63, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x65, 0x72,
+ 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+ 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x12, 0x30, 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65,
+ 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65,
+ 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x70, 0x72, 0x6f,
+ 0x64, 0x75, 0x63, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x46, 0x69, 0x6c,
+ 0x74, 0x65, 0x72, 0x1a, 0xb3, 0x01, 0x0a, 0x11, 0x42, 0x75, 0x69, 0x6c,
+ 0x74, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63,
+ 0x65, 0x12, 0x3c, 0x0a, 0x1a, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
+ 0x5f, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73,
+ 0x68, 0x6f, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x18, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6c,
+ 0x6f, 0x63, 0x6b, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x74,
+ 0x69, 0x6e, 0x67, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x69, 0x73, 0x61, 0x62,
+ 0x6c, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64,
+ 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x69, 0x73,
+ 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f,
+ 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11,
+ 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65,
+ 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x77, 0x0a, 0x0e, 0x50, 0x72, 0x6f,
+ 0x64, 0x75, 0x63, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
+ 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x5f,
+ 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
+ 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65,
+ 0x12, 0x1e, 0x0a, 0x0b, 0x73, 0x68, 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65,
+ 0x5f, 0x6b, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x73,
+ 0x68, 0x6d, 0x53, 0x69, 0x7a, 0x65, 0x4b, 0x62, 0x12, 0x20, 0x0a, 0x0c,
+ 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x6b, 0x62,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x65,
+ 0x53, 0x69, 0x7a, 0x65, 0x4b, 0x62, 0x1a, 0xe4, 0x01, 0x0a, 0x0e, 0x53,
+ 0x74, 0x61, 0x74, 0x73, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+ 0x61, 0x12, 0x2e, 0x0a, 0x13, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72,
+ 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x64,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x74, 0x72, 0x69, 0x67,
+ 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x49,
+ 0x64, 0x12, 0x32, 0x0a, 0x15, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72,
+ 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75,
+ 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x13, 0x74, 0x72,
+ 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x55, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x72, 0x69,
+ 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
+ 0x12, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x64, 0x12, 0x3c, 0x0a, 0x1a, 0x74,
+ 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x75,
+ 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69,
+ 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x18, 0x74, 0x72, 0x69,
+ 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x75, 0x62, 0x73, 0x63,
+ 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x1a, 0x4c, 0x0a,
+ 0x12, 0x47, 0x75, 0x61, 0x72, 0x64, 0x72, 0x61, 0x69, 0x6c, 0x4f, 0x76,
+ 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x12, 0x36, 0x0a, 0x18, 0x6d,
+ 0x61, 0x78, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x70, 0x65,
+ 0x72, 0x5f, 0x64, 0x61, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x6d, 0x61, 0x78, 0x55, 0x70,
+ 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x65, 0x72, 0x44, 0x61, 0x79, 0x42, 0x79,
+ 0x74, 0x65, 0x73, 0x1a, 0xa0, 0x03, 0x0a, 0x0d, 0x54, 0x72, 0x69, 0x67,
+ 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x59, 0x0a,
+ 0x0c, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5f, 0x6d, 0x6f, 0x64,
+ 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x70, 0x65,
+ 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4d,
+ 0x6f, 0x64, 0x65, 0x52, 0x0b, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72,
+ 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x4e, 0x0a, 0x08, 0x74, 0x72, 0x69, 0x67,
+ 0x67, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32,
+ 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72,
+ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67,
+ 0x65, 0x72, 0x52, 0x08, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73,
+ 0x12, 0x2c, 0x0a, 0x12, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5f,
+ 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65,
+ 0x72, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x1a, 0x71,
+ 0x0a, 0x07, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x12, 0x0a,
+ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x72, 0x6f,
+ 0x64, 0x75, 0x63, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x72,
+ 0x65, 0x67, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11,
+ 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65,
+ 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x74, 0x6f,
+ 0x70, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x70, 0x44, 0x65,
+ 0x6c, 0x61, 0x79, 0x4d, 0x73, 0x22, 0x43, 0x0a, 0x0b, 0x54, 0x72, 0x69,
+ 0x67, 0x67, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0f, 0x0a, 0x0b,
+ 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
+ 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x54,
+ 0x52, 0x41, 0x43, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c,
+ 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x54, 0x52, 0x41, 0x43, 0x49, 0x4e, 0x47,
+ 0x10, 0x02, 0x1a, 0x40, 0x0a, 0x16, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d,
+ 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x12, 0x26, 0x0a, 0x0f, 0x63, 0x6c, 0x65, 0x61,
+ 0x72, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x63, 0x6c, 0x65, 0x61, 0x72,
+ 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x4d, 0x73, 0x22, 0x55, 0x0a, 0x15,
+ 0x4c, 0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x6f, 0x64, 0x65,
+ 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a,
+ 0x12, 0x4c, 0x4f, 0x43, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x55, 0x4e,
+ 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a,
+ 0x0e, 0x4c, 0x4f, 0x43, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x43, 0x4c,
+ 0x45, 0x41, 0x52, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x4f, 0x43,
+ 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x10, 0x02, 0x4a,
+ 0x04, 0x08, 0x0f, 0x10, 0x10, 0x22, 0xe4, 0x03, 0x0a, 0x0f, 0x48, 0x65,
0x61, 0x70, 0x70, 0x72, 0x6f, 0x66, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73,
- 0x44, 0x75, 0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x14,
- 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44, 0x75,
- 0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x0a, 0x10,
- 0x73, 0x68, 0x6d, 0x65, 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62,
- 0x79, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e,
- 0x73, 0x68, 0x6d, 0x65, 0x6d, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74,
- 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f,
- 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08,
- 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x43, 0x6c, 0x69, 0x65, 0x6e,
- 0x74, 0x1a, 0x64, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75,
+ 0x67, 0x12, 0x36, 0x0a, 0x17, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e,
+ 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x62,
+ 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x15,
+ 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x74, 0x65,
+ 0x72, 0x76, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x27, 0x0a,
+ 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6d, 0x64,
+ 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e,
+ 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6d, 0x64, 0x6c, 0x69,
+ 0x6e, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x04, 0x20,
+ 0x03, 0x28, 0x04, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03,
+ 0x61, 0x6c, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61,
+ 0x6c, 0x6c, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73,
+ 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78,
+ 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x73, 0x6b, 0x69, 0x70,
+ 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78,
+ 0x12, 0x6b, 0x0a, 0x16, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f,
+ 0x75, 0x73, 0x5f, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x70,
+ 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x66, 0x64,
+ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x69,
+ 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44, 0x75, 0x6d, 0x70, 0x43, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x52, 0x14, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75,
0x6f, 0x75, 0x73, 0x44, 0x75, 0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x12, 0x22, 0x0a, 0x0d, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x70, 0x68,
- 0x61, 0x73, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d,
- 0x52, 0x0b, 0x64, 0x75, 0x6d, 0x70, 0x50, 0x68, 0x61, 0x73, 0x65, 0x4d,
- 0x73, 0x12, 0x28, 0x0a, 0x10, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x69, 0x6e,
- 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6d, 0x73, 0x18, 0x06, 0x20,
- 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x64, 0x75, 0x6d, 0x70, 0x49, 0x6e, 0x74,
- 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x73, 0x2a, 0x8e, 0x01, 0x0a, 0x0c,
- 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6f, 0x67, 0x49, 0x64,
- 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x45, 0x46, 0x41,
- 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49, 0x44,
- 0x5f, 0x52, 0x41, 0x44, 0x49, 0x4f, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a,
- 0x4c, 0x49, 0x44, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x53, 0x10, 0x02,
- 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x59, 0x53, 0x54,
- 0x45, 0x4d, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49, 0x44, 0x5f,
- 0x43, 0x52, 0x41, 0x53, 0x48, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x4c,
- 0x49, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x53, 0x10, 0x05, 0x12, 0x10,
- 0x0a, 0x0c, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x45, 0x43, 0x55, 0x52, 0x49,
- 0x54, 0x59, 0x10, 0x06, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x44, 0x5f,
- 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x10, 0x07, 0x2a, 0x9b, 0x01, 0x0a,
- 0x12, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6f, 0x67, 0x50,
- 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x10, 0x50,
- 0x52, 0x49, 0x4f, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46,
- 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x52, 0x49,
- 0x4f, 0x5f, 0x55, 0x4e, 0x55, 0x53, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10,
- 0x0a, 0x0c, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x56, 0x45, 0x52, 0x42, 0x4f,
- 0x53, 0x45, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f,
- 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09,
- 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x04, 0x12,
- 0x0d, 0x0a, 0x09, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x57, 0x41, 0x52, 0x4e,
- 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x45,
- 0x52, 0x52, 0x4f, 0x52, 0x10, 0x06, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52,
- 0x49, 0x4f, 0x5f, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x07, 0x2a, 0xbf,
- 0x06, 0x0a, 0x0f, 0x4d, 0x65, 0x6d, 0x69, 0x6e, 0x66, 0x6f, 0x43, 0x6f,
- 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45,
- 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
- 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x4d,
- 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x54,
- 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45,
- 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x46, 0x52,
- 0x45, 0x45, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49,
- 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x41, 0x56, 0x41, 0x49,
- 0x4c, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x4d,
- 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x42, 0x55, 0x46, 0x46, 0x45,
- 0x52, 0x53, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x4d, 0x49,
- 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x44, 0x10, 0x05,
+ 0x67, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x68, 0x6d, 0x65, 0x6d, 0x5f, 0x73,
+ 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20,
+ 0x01, 0x28, 0x04, 0x52, 0x0e, 0x73, 0x68, 0x6d, 0x65, 0x6d, 0x53, 0x69,
+ 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x62,
+ 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18,
+ 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
+ 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x1a, 0x64, 0x0a, 0x14, 0x43, 0x6f,
+ 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44, 0x75, 0x6d, 0x70,
+ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x22, 0x0a, 0x0d, 0x64, 0x75,
+ 0x6d, 0x70, 0x5f, 0x70, 0x68, 0x61, 0x73, 0x65, 0x5f, 0x6d, 0x73, 0x18,
+ 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x64, 0x75, 0x6d, 0x70, 0x50,
+ 0x68, 0x61, 0x73, 0x65, 0x4d, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x64, 0x75,
+ 0x6d, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f,
+ 0x6d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x64, 0x75,
+ 0x6d, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x73,
+ 0x2a, 0x8e, 0x01, 0x0a, 0x0c, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x4c, 0x6f, 0x67, 0x49, 0x64, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x49, 0x44,
+ 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0d,
+ 0x0a, 0x09, 0x4c, 0x49, 0x44, 0x5f, 0x52, 0x41, 0x44, 0x49, 0x4f, 0x10,
+ 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x44, 0x5f, 0x45, 0x56, 0x45,
+ 0x4e, 0x54, 0x53, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x44,
+ 0x5f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x10, 0x03, 0x12, 0x0d, 0x0a,
+ 0x09, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x52, 0x41, 0x53, 0x48, 0x10, 0x04,
+ 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54,
+ 0x53, 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x49, 0x44, 0x5f, 0x53,
+ 0x45, 0x43, 0x55, 0x52, 0x49, 0x54, 0x59, 0x10, 0x06, 0x12, 0x0e, 0x0a,
+ 0x0a, 0x4c, 0x49, 0x44, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x10,
+ 0x07, 0x2a, 0x9b, 0x01, 0x0a, 0x12, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+ 0x64, 0x4c, 0x6f, 0x67, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79,
+ 0x12, 0x14, 0x0a, 0x10, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x55, 0x4e, 0x53,
+ 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f,
+ 0x0a, 0x0b, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x55, 0x4e, 0x55, 0x53, 0x45,
+ 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, 0x49, 0x4f, 0x5f,
+ 0x56, 0x45, 0x52, 0x42, 0x4f, 0x53, 0x45, 0x10, 0x02, 0x12, 0x0e, 0x0a,
+ 0x0a, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10,
+ 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x49, 0x4e,
+ 0x46, 0x4f, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x50, 0x52, 0x49, 0x4f,
+ 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, 0x50,
+ 0x52, 0x49, 0x4f, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x06, 0x12,
+ 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x46, 0x41, 0x54, 0x41,
+ 0x4c, 0x10, 0x07, 0x2a, 0xbf, 0x06, 0x0a, 0x0f, 0x4d, 0x65, 0x6d, 0x69,
+ 0x6e, 0x66, 0x6f, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12,
+ 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x55,
+ 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00,
+ 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
+ 0x4d, 0x45, 0x4d, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x01, 0x12,
+ 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d,
+ 0x45, 0x4d, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x10, 0x02, 0x12, 0x19, 0x0a,
+ 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d,
+ 0x5f, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x03,
+ 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
+ 0x42, 0x55, 0x46, 0x46, 0x45, 0x52, 0x53, 0x10, 0x04, 0x12, 0x12, 0x0a,
+ 0x0e, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x41, 0x43,
+ 0x48, 0x45, 0x44, 0x10, 0x05, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d,
+ 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x43, 0x41,
+ 0x43, 0x48, 0x45, 0x44, 0x10, 0x06, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45,
+ 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45,
+ 0x10, 0x07, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
+ 0x4f, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x08,
+ 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
+ 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10,
+ 0x09, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
+ 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x4e,
+ 0x4f, 0x4e, 0x10, 0x0a, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49,
+ 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46,
+ 0x49, 0x4c, 0x45, 0x10, 0x0b, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d,
+ 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56,
+ 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x0c, 0x12, 0x17, 0x0a, 0x13,
+ 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x55, 0x4e, 0x45, 0x56,
+ 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x0d, 0x12, 0x13, 0x0a,
+ 0x0f, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x4c, 0x4f,
+ 0x43, 0x4b, 0x45, 0x44, 0x10, 0x0e, 0x12, 0x16, 0x0a, 0x12, 0x4d, 0x45,
+ 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x54,
+ 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x0f, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45,
+ 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x46,
+ 0x52, 0x45, 0x45, 0x10, 0x10, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x45, 0x4d,
+ 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x44, 0x49, 0x52, 0x54, 0x59, 0x10, 0x11,
+ 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
+ 0x57, 0x52, 0x49, 0x54, 0x45, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x12, 0x12,
+ 0x16, 0x0a, 0x12, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41,
+ 0x4e, 0x4f, 0x4e, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x13, 0x12,
+ 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d,
+ 0x41, 0x50, 0x50, 0x45, 0x44, 0x10, 0x14, 0x12, 0x11, 0x0a, 0x0d, 0x4d,
+ 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x48, 0x4d, 0x45, 0x4d,
+ 0x10, 0x15, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
+ 0x4f, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x10, 0x16, 0x12, 0x1c, 0x0a, 0x18,
+ 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x4c, 0x41, 0x42,
+ 0x5f, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45,
+ 0x10, 0x17, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
+ 0x4f, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f, 0x55, 0x4e, 0x52, 0x45, 0x43,
+ 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x18, 0x12, 0x18,
+ 0x0a, 0x14, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4b, 0x45,
+ 0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x10, 0x19,
0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
- 0x53, 0x57, 0x41, 0x50, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x44, 0x10,
- 0x06, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
- 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x07, 0x12, 0x14, 0x0a,
- 0x10, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e, 0x41,
- 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x08, 0x12, 0x17, 0x0a, 0x13, 0x4d,
- 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56,
- 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x09, 0x12, 0x19, 0x0a, 0x15,
- 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e, 0x41, 0x43,
- 0x54, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x0a, 0x12,
- 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41,
- 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x0b,
- 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
- 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c,
- 0x45, 0x10, 0x0c, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
- 0x46, 0x4f, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42,
- 0x4c, 0x45, 0x10, 0x0d, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x45, 0x4d, 0x49,
- 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10,
- 0x0e, 0x12, 0x16, 0x0a, 0x12, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
- 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x10,
- 0x0f, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
- 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x10, 0x10,
- 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
- 0x44, 0x49, 0x52, 0x54, 0x59, 0x10, 0x11, 0x12, 0x15, 0x0a, 0x11, 0x4d,
- 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45,
- 0x42, 0x41, 0x43, 0x4b, 0x10, 0x12, 0x12, 0x16, 0x0a, 0x12, 0x4d, 0x45,
- 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x5f, 0x50,
- 0x41, 0x47, 0x45, 0x53, 0x10, 0x13, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45,
- 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x45, 0x44,
- 0x10, 0x14, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
- 0x4f, 0x5f, 0x53, 0x48, 0x4d, 0x45, 0x4d, 0x10, 0x15, 0x12, 0x10, 0x0a,
- 0x0c, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x4c, 0x41,
- 0x42, 0x10, 0x16, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
- 0x46, 0x4f, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4c,
- 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x17, 0x12, 0x1e, 0x0a,
- 0x1a, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x4c, 0x41,
- 0x42, 0x5f, 0x55, 0x4e, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41,
- 0x42, 0x4c, 0x45, 0x10, 0x18, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x4d,
- 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x5f,
- 0x53, 0x54, 0x41, 0x43, 0x4b, 0x10, 0x19, 0x12, 0x17, 0x0a, 0x13, 0x4d,
- 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x5f,
- 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x1a, 0x12, 0x18, 0x0a, 0x14,
- 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4f, 0x4d, 0x4d,
- 0x49, 0x54, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x1b, 0x12, 0x17,
- 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4f,
- 0x4d, 0x4d, 0x49, 0x54, 0x45, 0x44, 0x5f, 0x41, 0x53, 0x10, 0x1c, 0x12,
- 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x56,
- 0x4d, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c,
- 0x10, 0x1d, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
- 0x4f, 0x5f, 0x56, 0x4d, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x55, 0x53,
- 0x45, 0x44, 0x10, 0x1e, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49,
+ 0x50, 0x41, 0x47, 0x45, 0x5f, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10,
+ 0x1a, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
+ 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x5f, 0x4c, 0x49, 0x4d, 0x49,
+ 0x54, 0x10, 0x1b, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
+ 0x46, 0x4f, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x45, 0x44, 0x5f,
+ 0x41, 0x53, 0x10, 0x1c, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49,
0x4e, 0x46, 0x4f, 0x5f, 0x56, 0x4d, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f,
- 0x43, 0x48, 0x55, 0x4e, 0x4b, 0x10, 0x1f, 0x12, 0x15, 0x0a, 0x11, 0x4d,
- 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4d, 0x41, 0x5f, 0x54,
- 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x20, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45,
- 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4d, 0x41, 0x5f, 0x46, 0x52,
- 0x45, 0x45, 0x10, 0x21, 0x2a, 0xff, 0x14, 0x0a, 0x0e, 0x56, 0x6d, 0x73,
- 0x74, 0x61, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12,
- 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e,
- 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12,
- 0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52,
- 0x5f, 0x46, 0x52, 0x45, 0x45, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10,
- 0x01, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
- 0x4e, 0x52, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x42, 0x41, 0x54,
- 0x43, 0x48, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49,
- 0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x03, 0x12, 0x19, 0x0a,
- 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41,
- 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x04,
- 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
- 0x52, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46,
- 0x49, 0x4c, 0x45, 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53,
- 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56,
- 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x06, 0x12, 0x19, 0x0a, 0x15,
- 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x55, 0x4e,
- 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x07, 0x12,
- 0x13, 0x0a, 0x0f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52,
- 0x5f, 0x4d, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14,
- 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x4e,
- 0x4f, 0x4e, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x09, 0x12, 0x14,
- 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
- 0x4d, 0x41, 0x50, 0x50, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x18, 0x0a, 0x14,
- 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x46, 0x49,
- 0x4c, 0x45, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x0b, 0x12, 0x13,
- 0x0a, 0x0f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
- 0x44, 0x49, 0x52, 0x54, 0x59, 0x10, 0x0c, 0x12, 0x17, 0x0a, 0x13, 0x56,
- 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57, 0x52, 0x49,
- 0x54, 0x45, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x0d, 0x12, 0x1e, 0x0a, 0x1a,
- 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x4c,
- 0x41, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42,
- 0x4c, 0x45, 0x10, 0x0e, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f, 0x55,
- 0x4e, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45,
- 0x10, 0x0f, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x4e, 0x52, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x5f, 0x54, 0x41, 0x42,
- 0x4c, 0x45, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x10, 0x12, 0x1a,
- 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
- 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b,
- 0x10, 0x11, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x4e, 0x52, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x48, 0x45, 0x41, 0x44,
- 0x10, 0x12, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x4e, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x45,
- 0x10, 0x13, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x4e, 0x52, 0x5f, 0x42, 0x4f, 0x55, 0x4e, 0x43, 0x45, 0x10, 0x14,
- 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
- 0x52, 0x5f, 0x56, 0x4d, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x57, 0x52, 0x49,
- 0x54, 0x45, 0x10, 0x15, 0x12, 0x26, 0x0a, 0x22, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x56, 0x4d, 0x53, 0x43, 0x41, 0x4e,
- 0x5f, 0x49, 0x4d, 0x4d, 0x45, 0x44, 0x49, 0x41, 0x54, 0x45, 0x5f, 0x52,
- 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x10, 0x16, 0x12, 0x1c, 0x0a, 0x18,
- 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57, 0x52,
- 0x49, 0x54, 0x45, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x54, 0x45, 0x4d, 0x50,
- 0x10, 0x17, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44,
- 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x18, 0x12, 0x1b, 0x0a, 0x17, 0x56,
- 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x53, 0x4f,
- 0x4c, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x19,
- 0x12, 0x13, 0x0a, 0x0f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
- 0x52, 0x5f, 0x53, 0x48, 0x4d, 0x45, 0x4d, 0x10, 0x1a, 0x12, 0x15, 0x0a,
- 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44,
- 0x49, 0x52, 0x54, 0x49, 0x45, 0x44, 0x10, 0x1b, 0x12, 0x15, 0x0a, 0x11,
- 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57, 0x52,
- 0x49, 0x54, 0x54, 0x45, 0x4e, 0x10, 0x1c, 0x12, 0x1b, 0x0a, 0x17, 0x56,
+ 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x1d, 0x12, 0x18, 0x0a, 0x14, 0x4d,
+ 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x56, 0x4d, 0x41, 0x4c, 0x4c,
+ 0x4f, 0x43, 0x5f, 0x55, 0x53, 0x45, 0x44, 0x10, 0x1e, 0x12, 0x19, 0x0a,
+ 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x56, 0x4d, 0x41,
+ 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x43, 0x48, 0x55, 0x4e, 0x4b, 0x10, 0x1f,
+ 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
+ 0x43, 0x4d, 0x41, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x20, 0x12,
+ 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43,
+ 0x4d, 0x41, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x10, 0x21, 0x2a, 0xff, 0x14,
+ 0x0a, 0x0e, 0x56, 0x6d, 0x73, 0x74, 0x61, 0x74, 0x43, 0x6f, 0x75, 0x6e,
+ 0x74, 0x65, 0x72, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54,
+ 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
+ 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54,
+ 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x5f, 0x50,
+ 0x41, 0x47, 0x45, 0x53, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d,
+ 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x4c, 0x4c, 0x4f,
+ 0x43, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48, 0x10, 0x02, 0x12, 0x1b, 0x0a,
+ 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49,
+ 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e,
+ 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x41,
+ 0x4e, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54,
+ 0x49, 0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x05, 0x12, 0x19,
+ 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
+ 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10,
+ 0x06, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x4e, 0x52, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42,
+ 0x4c, 0x45, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x56, 0x4d, 0x53, 0x54,
+ 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4d, 0x4c, 0x4f, 0x43, 0x4b, 0x10,
+ 0x08, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x4e, 0x52, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x5f, 0x50, 0x41, 0x47, 0x45,
+ 0x53, 0x10, 0x09, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41,
+ 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x45, 0x44, 0x10,
+ 0x0a, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x4e, 0x52, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x50, 0x41, 0x47, 0x45,
+ 0x53, 0x10, 0x0b, 0x12, 0x13, 0x0a, 0x0f, 0x56, 0x4d, 0x53, 0x54, 0x41,
+ 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52, 0x54, 0x59, 0x10, 0x0c,
+ 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
+ 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x42, 0x41, 0x43, 0x4b, 0x10,
+ 0x0d, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x4e, 0x52, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4c,
+ 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x0e, 0x12, 0x20, 0x0a,
+ 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53,
+ 0x4c, 0x41, 0x42, 0x5f, 0x55, 0x4e, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49,
+ 0x4d, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x0f, 0x12, 0x1e, 0x0a, 0x1a, 0x56,
0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x50, 0x41, 0x47,
- 0x45, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x1d,
- 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x57,
- 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x53, 0x45, 0x54, 0x5f, 0x52, 0x45,
- 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x1e, 0x12, 0x1e, 0x0a, 0x1a, 0x56,
- 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x49, 0x4e,
- 0x47, 0x53, 0x45, 0x54, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x41, 0x54,
- 0x45, 0x10, 0x1f, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41,
- 0x54, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x53, 0x45, 0x54,
- 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d,
- 0x10, 0x20, 0x12, 0x28, 0x0a, 0x24, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41,
- 0x4e, 0x53, 0x50, 0x41, 0x52, 0x45, 0x4e, 0x54, 0x5f, 0x48, 0x55, 0x47,
- 0x45, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x21, 0x12, 0x16, 0x0a, 0x12,
- 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x46, 0x52,
- 0x45, 0x45, 0x5f, 0x43, 0x4d, 0x41, 0x10, 0x22, 0x12, 0x17, 0x0a, 0x13,
- 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x57,
- 0x41, 0x50, 0x43, 0x41, 0x43, 0x48, 0x45, 0x10, 0x23, 0x12, 0x1d, 0x0a,
- 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44,
- 0x49, 0x52, 0x54, 0x59, 0x5f, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f,
- 0x4c, 0x44, 0x10, 0x24, 0x12, 0x28, 0x0a, 0x24, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52, 0x54, 0x59, 0x5f,
- 0x42, 0x41, 0x43, 0x4b, 0x47, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x54,
- 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x10, 0x25, 0x12, 0x11,
- 0x0a, 0x0d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x50,
- 0x47, 0x49, 0x4e, 0x10, 0x26, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x4d, 0x53,
- 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x50, 0x47, 0x4f, 0x55, 0x54, 0x10,
- 0x27, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
- 0x50, 0x47, 0x50, 0x47, 0x4f, 0x55, 0x54, 0x43, 0x4c, 0x45, 0x41, 0x4e,
- 0x10, 0x28, 0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x50, 0x53, 0x57, 0x50, 0x49, 0x4e, 0x10, 0x29, 0x12, 0x12, 0x0a,
- 0x0e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x53, 0x57, 0x50,
- 0x4f, 0x55, 0x54, 0x10, 0x2a, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53,
- 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f,
- 0x44, 0x4d, 0x41, 0x10, 0x2b, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53,
- 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f,
- 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x2c, 0x12, 0x1a, 0x0a, 0x16,
- 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x4c, 0x4c,
- 0x4f, 0x43, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x2d,
- 0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
- 0x47, 0x46, 0x52, 0x45, 0x45, 0x10, 0x2e, 0x12, 0x15, 0x0a, 0x11, 0x56,
- 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x43, 0x54, 0x49,
- 0x56, 0x41, 0x54, 0x45, 0x10, 0x2f, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d,
- 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x44, 0x45, 0x41, 0x43, 0x54,
- 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x30, 0x12, 0x12, 0x0a, 0x0e, 0x56,
- 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x46, 0x41, 0x55, 0x4c,
- 0x54, 0x10, 0x31, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41,
- 0x54, 0x5f, 0x50, 0x47, 0x4d, 0x41, 0x4a, 0x46, 0x41, 0x55, 0x4c, 0x54,
- 0x10, 0x32, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x50, 0x47, 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x44, 0x4d,
- 0x41, 0x10, 0x33, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41,
- 0x54, 0x5f, 0x50, 0x47, 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x4e,
- 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x34, 0x12, 0x1b, 0x0a, 0x17, 0x56,
+ 0x45, 0x5f, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x41, 0x47, 0x45,
+ 0x53, 0x10, 0x10, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41,
+ 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x5f,
+ 0x53, 0x54, 0x41, 0x43, 0x4b, 0x10, 0x11, 0x12, 0x16, 0x0a, 0x12, 0x56,
+ 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4f, 0x56, 0x45,
+ 0x52, 0x48, 0x45, 0x41, 0x44, 0x10, 0x12, 0x12, 0x16, 0x0a, 0x12, 0x56,
+ 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x55, 0x4e, 0x53,
+ 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x13, 0x12, 0x14, 0x0a, 0x10, 0x56,
+ 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x42, 0x4f, 0x55,
+ 0x4e, 0x43, 0x45, 0x10, 0x14, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x56, 0x4d, 0x53, 0x43, 0x41,
+ 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x15, 0x12, 0x26, 0x0a,
+ 0x22, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x56,
+ 0x4d, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x49, 0x4d, 0x4d, 0x45, 0x44, 0x49,
+ 0x41, 0x54, 0x45, 0x5f, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x10,
+ 0x16, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x4e, 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x42, 0x41, 0x43, 0x4b,
+ 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x10, 0x17, 0x12, 0x1b, 0x0a, 0x17, 0x56,
+ 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x53, 0x4f,
+ 0x4c, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x18,
+ 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
+ 0x52, 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x46,
+ 0x49, 0x4c, 0x45, 0x10, 0x19, 0x12, 0x13, 0x0a, 0x0f, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x48, 0x4d, 0x45, 0x4d,
+ 0x10, 0x1a, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52, 0x54, 0x49, 0x45, 0x44, 0x10,
+ 0x1b, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x4e, 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x54, 0x45, 0x4e, 0x10, 0x1c,
+ 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
+ 0x52, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e,
+ 0x4e, 0x45, 0x44, 0x10, 0x1d, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x53,
+ 0x45, 0x54, 0x5f, 0x52, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x1e,
+ 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x57,
+ 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x53, 0x45, 0x54, 0x5f, 0x41, 0x43,
+ 0x54, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x1f, 0x12, 0x21, 0x0a, 0x1d,
+ 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x49,
+ 0x4e, 0x47, 0x53, 0x45, 0x54, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x52, 0x45,
+ 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x10, 0x20, 0x12, 0x28, 0x0a, 0x24, 0x56,
+ 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x4e, 0x4f,
+ 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x50, 0x41, 0x52, 0x45, 0x4e,
+ 0x54, 0x5f, 0x48, 0x55, 0x47, 0x45, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10,
+ 0x21, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x4e, 0x52, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x5f, 0x43, 0x4d, 0x41, 0x10,
+ 0x22, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x4e, 0x52, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x43, 0x41, 0x43, 0x48, 0x45,
+ 0x10, 0x23, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52, 0x54, 0x59, 0x5f, 0x54, 0x48,
+ 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x10, 0x24, 0x12, 0x28, 0x0a,
+ 0x24, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44,
+ 0x49, 0x52, 0x54, 0x59, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x47, 0x52, 0x4f,
+ 0x55, 0x4e, 0x44, 0x5f, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c,
+ 0x44, 0x10, 0x25, 0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4d, 0x53, 0x54, 0x41,
+ 0x54, 0x5f, 0x50, 0x47, 0x50, 0x47, 0x49, 0x4e, 0x10, 0x26, 0x12, 0x12,
+ 0x0a, 0x0e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x50,
+ 0x47, 0x4f, 0x55, 0x54, 0x10, 0x27, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d,
+ 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x50, 0x47, 0x4f, 0x55, 0x54,
+ 0x43, 0x4c, 0x45, 0x41, 0x4e, 0x10, 0x28, 0x12, 0x11, 0x0a, 0x0d, 0x56,
+ 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x53, 0x57, 0x50, 0x49, 0x4e,
+ 0x10, 0x29, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x50, 0x53, 0x57, 0x50, 0x4f, 0x55, 0x54, 0x10, 0x2a, 0x12, 0x16,
+ 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41,
+ 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x2b, 0x12, 0x19,
+ 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41,
+ 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10,
+ 0x2c, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x4d, 0x4f, 0x56, 0x41,
+ 0x42, 0x4c, 0x45, 0x10, 0x2d, 0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x46, 0x52, 0x45, 0x45, 0x10, 0x2e,
+ 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
+ 0x47, 0x41, 0x43, 0x54, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x2f, 0x12,
+ 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47,
+ 0x44, 0x45, 0x41, 0x43, 0x54, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x30,
+ 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
+ 0x47, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x31, 0x12, 0x15, 0x0a, 0x11,
+ 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x4d, 0x41, 0x4a,
+ 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x32, 0x12, 0x17, 0x0a, 0x13, 0x56,
0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x52, 0x45, 0x46, 0x49,
- 0x4c, 0x4c, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x35,
- 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
- 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50,
- 0x44, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x36, 0x12, 0x20, 0x0a, 0x1c, 0x56,
- 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41,
- 0x4c, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4e, 0x4f, 0x52,
- 0x4d, 0x41, 0x4c, 0x10, 0x37, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53,
+ 0x4c, 0x4c, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x33, 0x12, 0x1a, 0x0a, 0x16,
+ 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x52, 0x45, 0x46,
+ 0x49, 0x4c, 0x4c, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x34,
+ 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
+ 0x47, 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x4d, 0x4f, 0x56, 0x41,
+ 0x42, 0x4c, 0x45, 0x10, 0x35, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53,
0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f,
- 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42,
- 0x4c, 0x45, 0x10, 0x38, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54,
+ 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x36,
+ 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
+ 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50,
+ 0x44, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x37, 0x12, 0x21,
+ 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53,
+ 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f,
+ 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x38, 0x12, 0x1d, 0x0a,
+ 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54,
+ 0x45, 0x41, 0x4c, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x44,
+ 0x4d, 0x41, 0x10, 0x39, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54,
0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x44,
- 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x39, 0x12,
- 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47,
- 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54,
- 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x3a, 0x12, 0x21, 0x0a,
- 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54,
- 0x45, 0x41, 0x4c, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4d,
- 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x3b, 0x12, 0x1c, 0x0a, 0x18,
+ 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c,
+ 0x10, 0x3a, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x44, 0x49, 0x52,
+ 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10,
+ 0x3b, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50,
+ 0x44, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x3c, 0x12, 0x1f, 0x0a, 0x1b, 0x56,
+ 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e,
+ 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4e, 0x4f, 0x52, 0x4d,
+ 0x41, 0x4c, 0x10, 0x3d, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54,
+ 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x4b, 0x53,
+ 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45,
+ 0x10, 0x3e, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45,
+ 0x43, 0x54, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x3f, 0x12, 0x1f, 0x0a, 0x1b,
0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41,
- 0x4e, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x44, 0x4d, 0x41,
- 0x10, 0x3c, 0x12, 0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x4b, 0x53, 0x57, 0x41,
- 0x50, 0x44, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x3d, 0x12,
- 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47,
- 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f,
- 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x3e, 0x12, 0x1c, 0x0a,
- 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43,
- 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x44, 0x4d,
- 0x41, 0x10, 0x3f, 0x12, 0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54, 0x41,
+ 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4e, 0x4f, 0x52,
+ 0x4d, 0x41, 0x4c, 0x10, 0x40, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x44,
+ 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c,
+ 0x45, 0x10, 0x41, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41,
0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52,
- 0x45, 0x43, 0x54, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x40,
- 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
- 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54,
- 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x41, 0x12, 0x21,
- 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53,
- 0x43, 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x54,
- 0x48, 0x52, 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x10, 0x42, 0x12, 0x17, 0x0a,
- 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x49, 0x4e,
- 0x4f, 0x44, 0x45, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x10, 0x43, 0x12, 0x18,
- 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x53, 0x4c, 0x41,
- 0x42, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x44,
- 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4b,
- 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x49, 0x4e, 0x4f, 0x44, 0x45, 0x53,
- 0x54, 0x45, 0x41, 0x4c, 0x10, 0x45, 0x12, 0x27, 0x0a, 0x23, 0x56, 0x4d,
- 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f,
- 0x4c, 0x4f, 0x57, 0x5f, 0x57, 0x4d, 0x41, 0x52, 0x4b, 0x5f, 0x48, 0x49,
- 0x54, 0x5f, 0x51, 0x55, 0x49, 0x43, 0x4b, 0x4c, 0x59, 0x10, 0x46, 0x12,
- 0x28, 0x0a, 0x24, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4b, 0x53,
- 0x57, 0x41, 0x50, 0x44, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x5f, 0x57, 0x4d,
- 0x41, 0x52, 0x4b, 0x5f, 0x48, 0x49, 0x54, 0x5f, 0x51, 0x55, 0x49, 0x43,
- 0x4b, 0x4c, 0x59, 0x10, 0x47, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53,
- 0x54, 0x41, 0x54, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x4f, 0x55, 0x54, 0x52,
- 0x55, 0x4e, 0x10, 0x48, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x53, 0x54, 0x41, 0x4c,
- 0x4c, 0x10, 0x49, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41,
- 0x54, 0x5f, 0x50, 0x47, 0x52, 0x4f, 0x54, 0x41, 0x54, 0x45, 0x44, 0x10,
- 0x4a, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
- 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x43, 0x41, 0x43,
- 0x48, 0x45, 0x10, 0x4b, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x53, 0x4c, 0x41, 0x42,
- 0x10, 0x4c, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
- 0x5f, 0x50, 0x47, 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x53,
- 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x4d, 0x12, 0x19, 0x0a, 0x15,
- 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x4d, 0x49, 0x47,
- 0x52, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x4e, 0x12,
- 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f,
- 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54,
- 0x45, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x4f, 0x12,
- 0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f,
- 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x5f, 0x53,
- 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x50, 0x12, 0x1b, 0x0a, 0x17,
- 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41,
- 0x43, 0x54, 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x10,
- 0x51, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
- 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x4c,
- 0x4c, 0x10, 0x52, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41,
- 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x46, 0x41,
- 0x49, 0x4c, 0x10, 0x53, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x53,
- 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x54, 0x12, 0x1e, 0x0a, 0x1a,
+ 0x45, 0x43, 0x54, 0x5f, 0x54, 0x48, 0x52, 0x4f, 0x54, 0x54, 0x4c, 0x45,
+ 0x10, 0x42, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+ 0x5f, 0x50, 0x47, 0x49, 0x4e, 0x4f, 0x44, 0x45, 0x53, 0x54, 0x45, 0x41,
+ 0x4c, 0x10, 0x43, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41,
+ 0x54, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e,
+ 0x4e, 0x45, 0x44, 0x10, 0x44, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53,
+ 0x54, 0x41, 0x54, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x49,
+ 0x4e, 0x4f, 0x44, 0x45, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x10, 0x45, 0x12,
+ 0x27, 0x0a, 0x23, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4b, 0x53,
+ 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4c, 0x4f, 0x57, 0x5f, 0x57, 0x4d, 0x41,
+ 0x52, 0x4b, 0x5f, 0x48, 0x49, 0x54, 0x5f, 0x51, 0x55, 0x49, 0x43, 0x4b,
+ 0x4c, 0x59, 0x10, 0x46, 0x12, 0x28, 0x0a, 0x24, 0x56, 0x4d, 0x53, 0x54,
+ 0x41, 0x54, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x48, 0x49,
+ 0x47, 0x48, 0x5f, 0x57, 0x4d, 0x41, 0x52, 0x4b, 0x5f, 0x48, 0x49, 0x54,
+ 0x5f, 0x51, 0x55, 0x49, 0x43, 0x4b, 0x4c, 0x59, 0x10, 0x47, 0x12, 0x15,
+ 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x41, 0x47,
+ 0x45, 0x4f, 0x55, 0x54, 0x52, 0x55, 0x4e, 0x10, 0x48, 0x12, 0x15, 0x0a,
+ 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x4f,
+ 0x43, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x10, 0x49, 0x12, 0x14, 0x0a, 0x10,
+ 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x52, 0x4f, 0x54,
+ 0x41, 0x54, 0x45, 0x44, 0x10, 0x4a, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d,
+ 0x53, 0x54, 0x41, 0x54, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x50, 0x41,
+ 0x47, 0x45, 0x43, 0x41, 0x43, 0x48, 0x45, 0x10, 0x4b, 0x12, 0x14, 0x0a,
+ 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x44, 0x52, 0x4f, 0x50,
+ 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x10, 0x4c, 0x12, 0x1c, 0x0a, 0x18, 0x56,
+ 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x4d, 0x49, 0x47, 0x52,
+ 0x41, 0x54, 0x45, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10,
+ 0x4d, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x50, 0x47, 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41,
+ 0x49, 0x4c, 0x10, 0x4e, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54,
+ 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x4d,
+ 0x49, 0x47, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e,
+ 0x45, 0x44, 0x10, 0x4f, 0x12, 0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54,
+ 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x46,
+ 0x52, 0x45, 0x45, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10,
+ 0x50, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x49, 0x53, 0x4f, 0x4c,
+ 0x41, 0x54, 0x45, 0x44, 0x10, 0x51, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d,
+ 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54,
+ 0x5f, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x10, 0x52, 0x12, 0x17, 0x0a, 0x13,
0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41,
- 0x43, 0x54, 0x5f, 0x44, 0x41, 0x45, 0x4d, 0x4f, 0x4e, 0x5f, 0x57, 0x41,
- 0x4b, 0x45, 0x10, 0x55, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54,
- 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42,
- 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x43, 0x55, 0x4c, 0x4c, 0x45,
- 0x44, 0x10, 0x56, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41,
- 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c,
- 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45,
- 0x44, 0x10, 0x57, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41,
- 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c,
- 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x52, 0x45, 0x53, 0x43, 0x55, 0x45,
- 0x44, 0x10, 0x58, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41,
- 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c,
- 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x4d, 0x4c, 0x4f, 0x43, 0x4b, 0x45,
- 0x44, 0x10, 0x59, 0x12, 0x24, 0x0a, 0x20, 0x56, 0x4d, 0x53, 0x54, 0x41,
- 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c,
- 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x4d, 0x55, 0x4e, 0x4c, 0x4f, 0x43,
- 0x4b, 0x45, 0x44, 0x10, 0x5a, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53,
- 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41,
- 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x43, 0x4c, 0x45, 0x41,
- 0x52, 0x45, 0x44, 0x10, 0x5b, 0x12, 0x23, 0x0a, 0x1f, 0x56, 0x4d, 0x53,
- 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41,
- 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x53, 0x54, 0x52, 0x41,
- 0x4e, 0x44, 0x45, 0x44, 0x10, 0x5c}};
+ 0x43, 0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x53, 0x12, 0x1a, 0x0a,
+ 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50,
+ 0x41, 0x43, 0x54, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10,
+ 0x54, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+ 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x44, 0x41, 0x45, 0x4d,
+ 0x4f, 0x4e, 0x5f, 0x57, 0x41, 0x4b, 0x45, 0x10, 0x55, 0x12, 0x21, 0x0a,
+ 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56,
+ 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f,
+ 0x43, 0x55, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x56, 0x12, 0x22, 0x0a, 0x1e,
+ 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49,
+ 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x53,
+ 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x57, 0x12, 0x22, 0x0a, 0x1e,
+ 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49,
+ 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x52,
+ 0x45, 0x53, 0x43, 0x55, 0x45, 0x44, 0x10, 0x58, 0x12, 0x22, 0x0a, 0x1e,
+ 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49,
+ 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x4d,
+ 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x59, 0x12, 0x24, 0x0a, 0x20,
+ 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49,
+ 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x4d,
+ 0x55, 0x4e, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x5a, 0x12, 0x22,
+ 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45,
+ 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53,
+ 0x5f, 0x43, 0x4c, 0x45, 0x41, 0x52, 0x45, 0x44, 0x10, 0x5b, 0x12, 0x23,
+ 0x0a, 0x1f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45,
+ 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53,
+ 0x5f, 0x53, 0x54, 0x52, 0x41, 0x4e, 0x44, 0x45, 0x44, 0x10, 0x5c}};
} // namespace perfetto
diff --git a/src/perfetto_cmd/trigger_producer.cc b/src/perfetto_cmd/trigger_producer.cc
index 45d6c4c63..c84716fae 100644
--- a/src/perfetto_cmd/trigger_producer.cc
+++ b/src/perfetto_cmd/trigger_producer.cc
@@ -87,4 +87,10 @@ void TriggerProducer::Flush(FlushRequestID,
PERFETTO_DFATAL("Attempted to Flush() on commandline producer");
}
+void TriggerProducer::ClearIncrementalState(const DataSourceInstanceID*,
+ size_t) {
+ PERFETTO_DFATAL(
+ "Attempted to ClearIncrementalState() on commandline producer");
+}
+
} // namespace perfetto
diff --git a/src/perfetto_cmd/trigger_producer.h b/src/perfetto_cmd/trigger_producer.h
index dfd189c91..6abab0e99 100644
--- a/src/perfetto_cmd/trigger_producer.h
+++ b/src/perfetto_cmd/trigger_producer.h
@@ -50,6 +50,8 @@ class TriggerProducer : public Producer {
void StartDataSource(DataSourceInstanceID, const DataSourceConfig&) override;
void StopDataSource(DataSourceInstanceID) override;
void Flush(FlushRequestID, const DataSourceInstanceID*, size_t) override;
+ void ClearIncrementalState(const DataSourceInstanceID* data_source_ids,
+ size_t num_data_sources) override;
private:
bool issued_callback_ = false;
diff --git a/src/profiling/memory/heapprofd_producer.h b/src/profiling/memory/heapprofd_producer.h
index d100be11c..567cca0a2 100644
--- a/src/profiling/memory/heapprofd_producer.h
+++ b/src/profiling/memory/heapprofd_producer.h
@@ -115,6 +115,8 @@ class HeapprofdProducer : public Producer, public UnwindingWorker::Delegate {
void Flush(FlushRequestID,
const DataSourceInstanceID* data_source_ids,
size_t num_data_sources) override;
+ void ClearIncrementalState(const DataSourceInstanceID* /*data_source_ids*/,
+ size_t /*num_data_sources*/) override {}
// TODO(fmayer): Refactor once/if we have generic reconnect logic.
void ConnectWithRetries(const char* socket_name);
diff --git a/src/protozero/proto_decoder_unittest.cc b/src/protozero/proto_decoder_unittest.cc
index 16efd9a97..2f5ab5356 100644
--- a/src/protozero/proto_decoder_unittest.cc
+++ b/src/protozero/proto_decoder_unittest.cc
@@ -32,19 +32,12 @@ using ::testing::Invoke;
using namespace proto_utils;
TEST(ProtoDecoderTest, ReadString) {
- Message message;
- ScatteredHeapBuffer delegate(512, 512);
- ScatteredStreamWriter writer(&delegate);
- delegate.set_writer(&writer);
- message.Reset(&writer);
+ HeapBuffered<Message> message;
static constexpr char kTestString[] = "test";
- message.AppendString(1, kTestString);
-
- delegate.AdjustUsedSizeOfCurrentSlice();
- auto used_range = delegate.slices()[0].GetUsedRange();
-
- TypedProtoDecoder<32, false> decoder(used_range.begin, used_range.size());
+ message->AppendString(1, kTestString);
+ std::vector<uint8_t> proto = message.SerializeAsArray();
+ TypedProtoDecoder<32, false> decoder(proto.data(), proto.size());
const auto& field = decoder.Get(1);
ASSERT_EQ(field.type(), ProtoWireType::kLengthDelimited);
diff --git a/src/traced/probes/ftrace/cpu_reader.cc b/src/traced/probes/ftrace/cpu_reader.cc
index fc2e720b4..436edfbe4 100644
--- a/src/traced/probes/ftrace/cpu_reader.cc
+++ b/src/traced/probes/ftrace/cpu_reader.cc
@@ -52,8 +52,6 @@ constexpr uint32_t kTypePadding = 29;
constexpr uint32_t kTypeTimeExtend = 30;
constexpr uint32_t kTypeTimeStamp = 31;
-constexpr uint32_t kMainThread = 255; // for METATRACE
-
struct PageHeader {
uint64_t timestamp;
uint64_t size;
@@ -401,7 +399,8 @@ void CpuReader::RunWorkerThread(size_t cpu,
// first CPU wakes up from the blocking read()/splice().
void CpuReader::Drain(const std::set<FtraceDataSource*>& data_sources) {
PERFETTO_DCHECK_THREAD(thread_checker_);
- PERFETTO_METATRACE("Drain(" + std::to_string(cpu_) + ")", kMainThread);
+ PERFETTO_METATRACE("Drain(" + std::to_string(cpu_) + ")",
+ base::MetaTrace::kMainThreadCpu);
auto page_blocks = pool_.BeginRead();
for (const auto& page_block : page_blocks) {
@@ -583,6 +582,15 @@ bool CpuReader::ParseEvent(uint16_t ftrace_event_id,
}
}
+ if (PERFETTO_UNLIKELY(info.proto_field_id ==
+ protos::pbzero::FtraceEvent::kTaskRenameFieldNumber)) {
+ // For task renames, we want to store that the pid was renamed. We use the
+ // common pid to reduce code complexity as in all the cases we care about,
+ // the common pid is the same as the renamed pid (the pid inside the event).
+ PERFETTO_DCHECK(metadata->last_seen_common_pid);
+ metadata->AddRenamePid(metadata->last_seen_common_pid);
+ }
+
// This finalizes |nested| and |proto_field| automatically.
message->Finalize();
metadata->FinishEvent();
diff --git a/src/traced/probes/ftrace/cpu_reader_unittest.cc b/src/traced/probes/ftrace/cpu_reader_unittest.cc
index fe2ca7635..0631ecb8f 100644
--- a/src/traced/probes/ftrace/cpu_reader_unittest.cc
+++ b/src/traced/probes/ftrace/cpu_reader_unittest.cc
@@ -902,6 +902,33 @@ TEST_F(CpuReaderTableTest, ParseAllFields) {
Contains(Pair(99u, k64BitUserspaceBlockDeviceId)));
}
+TEST(CpuReaderTest, TaskRenameEvent) {
+ 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
+ writer.WriteFixedString(16, "Goodbye"); // New Comm
+ 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(), &metadata));
+ EXPECT_THAT(metadata.rename_pids, Contains(9999));
+ EXPECT_THAT(metadata.pids, Contains(9999));
+}
+
TEST(CpuReaderTest, TranslateBlockDeviceIDToUserspace) {
const uint32_t kKernelBlockDeviceId = 271581216;
const BlockDeviceID kUserspaceBlockDeviceId = 66336;
diff --git a/src/traced/probes/ftrace/ftrace_controller.cc b/src/traced/probes/ftrace/ftrace_controller.cc
index eff826220..b1b379314 100644
--- a/src/traced/probes/ftrace/ftrace_controller.cc
+++ b/src/traced/probes/ftrace/ftrace_controller.cc
@@ -48,10 +48,9 @@ namespace perfetto {
namespace {
constexpr int kDefaultDrainPeriodMs = 100;
-constexpr int kFlushTimeoutMs = 500;
+constexpr int kControllerFlushTimeoutMs = 500;
constexpr int kMinDrainPeriodMs = 1;
constexpr int kMaxDrainPeriodMs = 1000 * 60;
-constexpr uint32_t kMainThread = 255; // for METATRACE
uint32_t ClampDrainPeriodMs(uint32_t drain_period_ms) {
if (drain_period_ms == 0) {
@@ -220,7 +219,7 @@ void FtraceController::OnCpuReaderFlush(size_t cpu,
void FtraceController::DrainCPUs(int generation) {
PERFETTO_DCHECK_THREAD(thread_checker_);
- PERFETTO_METATRACE("DrainCPUs()", kMainThread);
+ PERFETTO_METATRACE("DrainCPUs()", base::MetaTrace::kMainThreadCpu);
if (generation != generation_)
return;
@@ -279,7 +278,7 @@ void FtraceController::DrainCPUs(int generation) {
}
void FtraceController::UnblockReaders() {
- PERFETTO_METATRACE("UnblockReaders()", kMainThread);
+ PERFETTO_METATRACE("UnblockReaders()", base::MetaTrace::kMainThreadCpu);
// If a flush or a quit is pending, do nothing.
std::unique_lock<std::mutex> lock(thread_sync_.mutex);
@@ -357,25 +356,25 @@ void FtraceController::Flush(FlushRequestID flush_id) {
if (weak_this)
weak_this->OnFlushTimeout(flush_id);
},
- kFlushTimeoutMs);
+ kControllerFlushTimeoutMs);
}
void FtraceController::OnFlushTimeout(FlushRequestID flush_request_id) {
if (flush_request_id != cur_flush_request_id_)
return;
- uint64_t acks = 0; // For debugging purposes only.
+ std::string acks; // For debugging purposes only.
{
// Unlock the cpu readers and move on.
std::unique_lock<std::mutex> lock(thread_sync_.mutex);
- acks = thread_sync_.flush_acks.to_ulong();
+ acks = thread_sync_.flush_acks.to_string();
thread_sync_.flush_acks.reset();
if (thread_sync_.cmd == FtraceThreadSync::kFlush)
IssueThreadSyncCmd(FtraceThreadSync::kRun, std::move(lock));
}
- PERFETTO_ELOG("Ftrace flush(%" PRIu64 ") timed out. Acked cpus: 0x%" PRIx64,
- flush_request_id, acks);
+ PERFETTO_ELOG("Ftrace flush(%" PRIu64 ") timed out. Acked cpus mask: [%s]",
+ flush_request_id, acks.c_str());
cur_flush_request_id_ = 0;
NotifyFlushCompleteToStartedDataSources(flush_request_id);
}
diff --git a/src/traced/probes/ftrace/ftrace_metadata.cc b/src/traced/probes/ftrace/ftrace_metadata.cc
index 8660a852d..3ae8aaa96 100644
--- a/src/traced/probes/ftrace/ftrace_metadata.cc
+++ b/src/traced/probes/ftrace/ftrace_metadata.cc
@@ -24,6 +24,8 @@ FtraceMetadata::FtraceMetadata() {
// A sched_switch is 64 bytes, a page is 4096 bytes and we expect
// 2 pid's per sched_switch. 4096/64*2=128
pids.reserve(128);
+ // We expect to see only a small number of task rename events.
+ rename_pids.reserve(16);
}
void FtraceMetadata::AddDevice(BlockDeviceID device_id) {
@@ -63,6 +65,10 @@ void FtraceMetadata::AddPid(int32_t pid) {
pids.push_back(pid);
}
+void FtraceMetadata::AddRenamePid(int32_t pid) {
+ rename_pids.push_back(pid);
+}
+
void FtraceMetadata::FinishEvent() {
last_seen_device_id = 0;
#if PERFETTO_DCHECK_IS_ON()
@@ -74,6 +80,7 @@ void FtraceMetadata::FinishEvent() {
void FtraceMetadata::Clear() {
inode_and_device.clear();
pids.clear();
+ rename_pids.clear();
overwrite_count = 0;
FinishEvent();
}
diff --git a/src/traced/probes/ftrace/ftrace_metadata.h b/src/traced/probes/ftrace/ftrace_metadata.h
index 4e2e04a8c..9d8f98d91 100644
--- a/src/traced/probes/ftrace/ftrace_metadata.h
+++ b/src/traced/probes/ftrace/ftrace_metadata.h
@@ -44,11 +44,13 @@ struct FtraceMetadata {
// A vector not a set to keep the writer_fast.
std::vector<std::pair<Inode, BlockDeviceID>> inode_and_device;
std::vector<int32_t> pids;
+ std::vector<int32_t> rename_pids;
void AddDevice(BlockDeviceID);
void AddInode(Inode);
void AddPid(int32_t);
void AddCommonPid(int32_t);
+ void AddRenamePid(int32_t);
void Clear();
void FinishEvent();
};
diff --git a/src/traced/probes/probes_data_source.h b/src/traced/probes/probes_data_source.h
index 1e0e8cb5b..7c92ede7a 100644
--- a/src/traced/probes/probes_data_source.h
+++ b/src/traced/probes/probes_data_source.h
@@ -19,6 +19,7 @@
#include <functional>
+#include "perfetto/base/logging.h"
#include "perfetto/tracing/core/basic_types.h"
namespace perfetto {
@@ -33,6 +34,14 @@ class ProbesDataSource {
virtual void Start() = 0;
virtual void Flush(FlushRequestID, std::function<void()> callback) = 0;
+ // Only data sources that opt in via DataSourceDescriptor should receive this
+ // call.
+ virtual void ClearIncrementalState() {
+ PERFETTO_ELOG(
+ "ClearIncrementalState received by data source that doesn't provide "
+ "its own implementation.");
+ }
+
const TracingSessionID tracing_session_id;
const int type_id;
bool started = false; // Set by probes_producer.cc.
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index 193334474..ebe68675a 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -53,7 +53,7 @@ namespace {
constexpr uint32_t kInitialConnectionBackoffMs = 100;
constexpr uint32_t kMaxConnectionBackoffMs = 30 * 1000;
-// Should be larger than FtraceController::kFlushTimeoutMs.
+// Should be larger than FtraceController::kControllerFlushTimeoutMs.
constexpr uint32_t kFlushTimeoutMs = 1000;
constexpr char kFtraceSourceName[] = "linux.ftrace";
@@ -96,6 +96,7 @@ void ProbesProducer::OnConnect() {
{
DataSourceDescriptor desc;
desc.set_name(kProcessStatsSourceName);
+ desc.set_handles_incremental_state_clear(true);
endpoint_->RegisterDataSource(desc);
}
@@ -396,6 +397,19 @@ void ProbesProducer::OnFlushTimeout(FlushRequestID flush_request_id) {
endpoint_->NotifyFlushComplete(flush_request_id);
}
+void ProbesProducer::ClearIncrementalState(
+ const DataSourceInstanceID* data_source_ids,
+ size_t num_data_sources) {
+ for (size_t i = 0; i < num_data_sources; i++) {
+ DataSourceInstanceID ds_id = data_source_ids[i];
+ auto it = data_sources_.find(ds_id);
+ if (it == data_sources_.end() || !it->second->started)
+ continue;
+
+ it->second->ClearIncrementalState();
+ }
+}
+
// This function is called by the FtraceController in batches, whenever it has
// read one or more pages from one or more cpus and written that into the
// userspace tracing buffer. If more than one ftrace data sources are active,
@@ -414,8 +428,13 @@ void ProbesProducer::OnFtraceDataWrittenIntoDataSourceBuffers() {
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)
diff --git a/src/traced/probes/probes_producer.h b/src/traced/probes/probes_producer.h
index e8b3a6c37..2184830f3 100644
--- a/src/traced/probes/probes_producer.h
+++ b/src/traced/probes/probes_producer.h
@@ -54,6 +54,8 @@ class ProbesProducer : public Producer, public FtraceController::Observer {
void Flush(FlushRequestID,
const DataSourceInstanceID* data_source_ids,
size_t num_data_sources) override;
+ void ClearIncrementalState(const DataSourceInstanceID* data_source_ids,
+ size_t num_data_sources) override;
// FtraceController::Observer implementation.
void OnFtraceDataWrittenIntoDataSourceBuffers() override;
diff --git a/src/traced/probes/ps/process_stats_data_source.cc b/src/traced/probes/ps/process_stats_data_source.cc
index 40441e23d..524a8b468 100644
--- a/src/traced/probes/ps/process_stats_data_source.cc
+++ b/src/traced/probes/ps/process_stats_data_source.cc
@@ -176,6 +176,19 @@ void ProcessStatsDataSource::OnPids(const std::vector<int32_t>& pids) {
FinalizeCurPacket();
}
+void ProcessStatsDataSource::OnRenamePids(const std::vector<int32_t>& pids) {
+ PERFETTO_METATRACE("OnRenamePids", 0);
+ if (!enable_on_demand_dumps_)
+ return;
+ PERFETTO_DCHECK(!cur_ps_tree_);
+ for (int32_t pid : pids) {
+ auto pid_it = seen_pids_.find(pid);
+ if (pid_it == seen_pids_.end())
+ continue;
+ seen_pids_.erase(pid_it);
+ }
+}
+
void ProcessStatsDataSource::Flush(FlushRequestID,
std::function<void()> callback) {
// We shouldn't get this in the middle of WriteAllProcesses() or OnPids().
@@ -269,6 +282,11 @@ void ProcessStatsDataSource::StartNewPacketIfNeeded() {
cur_packet_ = writer_->NewTracePacket();
uint64_t now = static_cast<uint64_t>(base::GetBootTimeNs().count());
cur_packet_->set_timestamp(now);
+
+ if (did_clear_incremental_state_) {
+ cur_packet_->set_incremental_state_cleared(true);
+ did_clear_incremental_state_ = false;
+ }
}
protos::pbzero::ProcessTree* ProcessStatsDataSource::GetOrCreatePsTree() {
@@ -320,8 +338,8 @@ void ProcessStatsDataSource::Tick(
thiz.WriteAllProcessStats();
// We clear the cache every process_stats_cache_ttl_ticks_ ticks.
- if (++thiz.ticks_ == thiz.process_stats_cache_ttl_ticks_) {
- thiz.ticks_ = 0;
+ if (++thiz.cache_ticks_ == thiz.process_stats_cache_ttl_ticks_) {
+ thiz.cache_ticks_ = 0;
thiz.process_stats_cache_.clear();
}
}
@@ -487,4 +505,16 @@ bool ProcessStatsDataSource::WriteMemCounters(int32_t pid,
return proc_status_has_mem_counters;
}
+void ProcessStatsDataSource::ClearIncrementalState() {
+ PERFETTO_DLOG("ProcessStatsDataSource clearing incremental state.");
+ seen_pids_.clear();
+ skip_stats_for_pids_.clear();
+
+ cache_ticks_ = 0;
+ process_stats_cache_.clear();
+
+ // Set the relevant flag in the next packet.
+ did_clear_incremental_state_ = true;
+}
+
} // namespace perfetto
diff --git a/src/traced/probes/ps/process_stats_data_source.h b/src/traced/probes/ps/process_stats_data_source.h
index 96869475d..efea49487 100644
--- a/src/traced/probes/ps/process_stats_data_source.h
+++ b/src/traced/probes/ps/process_stats_data_source.h
@@ -57,10 +57,12 @@ class ProcessStatsDataSource : public ProbesDataSource {
base::WeakPtr<ProcessStatsDataSource> GetWeakPtr() const;
void WriteAllProcesses();
void OnPids(const std::vector<int32_t>& pids);
+ void OnRenamePids(const std::vector<int32_t>& pids);
// ProbesDataSource implementation.
void Start() override;
void Flush(FlushRequestID, std::function<void()> callback) override;
+ void ClearIncrementalState() override;
bool on_demand_dumps_enabled() const { return enable_on_demand_dumps_; }
@@ -120,7 +122,7 @@ class ProcessStatsDataSource : public ProbesDataSource {
// Fields for keeping track of the periodic stats/counters.
uint32_t poll_period_ms_ = 0;
- uint64_t ticks_ = 0;
+ uint64_t cache_ticks_ = 0;
protos::pbzero::ProcessStats* cur_ps_stats_ = nullptr;
protos::pbzero::ProcessStats_Process* cur_ps_stats_process_ = nullptr;
std::vector<bool> skip_stats_for_pids_;
@@ -130,6 +132,15 @@ class ProcessStatsDataSource : public ProbesDataSource {
uint32_t process_stats_cache_ttl_ticks_ = 0;
std::unordered_map<int32_t, CachedProcessStats> process_stats_cache_;
+ // If true, the next trace packet will have the |incremental_state_cleared|
+ // flag set. Set when handling a ClearIncrementalState call.
+ //
+ // TODO(rsavitski): initialized to true since the first packet also doesn't
+ // have any prior state to refer to. It might make more sense to let the
+ // tracing service set this for every first packet (as it does for
+ // |previous_packet_dropped|).
+ bool did_clear_incremental_state_ = true;
+
base::WeakPtrFactory<ProcessStatsDataSource> weak_factory_; // Keep last.
};
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 2dd9ebba7..0ccd7036a 100644
--- a/src/traced/probes/ps/process_stats_data_source_unittest.cc
+++ b/src/traced/probes/ps/process_stats_data_source_unittest.cc
@@ -18,20 +18,20 @@
#include <dirent.h>
-#include "perfetto/base/temp_file.h"
-#include "src/base/test/test_task_runner.h"
-#include "src/tracing/core/trace_writer_for_testing.h"
-
#include "gmock/gmock.h"
#include "gtest/gtest.h"
-
+#include "perfetto/base/temp_file.h"
#include "perfetto/trace/trace_packet.pb.h"
#include "perfetto/trace/trace_packet.pbzero.h"
+#include "src/base/test/test_task_runner.h"
+#include "src/tracing/core/trace_writer_for_testing.h"
using ::testing::_;
using ::testing::ElementsAreArray;
using ::testing::Invoke;
+using ::testing::Mock;
using ::testing::Return;
+using ::testing::Truly;
namespace perfetto {
namespace {
@@ -74,16 +74,32 @@ TEST_F(ProcessStatsDataSourceTest, WriteOnceProcess) {
.WillOnce(Return(std::string("foo\0bar\0baz\0", 12)));
data_source->OnPids({42});
- std::unique_ptr<protos::TracePacket> packet = writer_raw_->ParseProto();
- ASSERT_TRUE(packet->has_process_tree());
- ASSERT_EQ(packet->process_tree().processes_size(), 1);
- auto first_process = packet->process_tree().processes(0);
+
+ std::vector<protos::TracePacket> trace = writer_raw_->GetAllTracePackets();
+ ASSERT_EQ(trace.size(), 1);
+ 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);
- EXPECT_THAT(first_process.cmdline(), ElementsAreArray({"foo", "bar", "baz"}));
+ ASSERT_THAT(first_process.cmdline(), ElementsAreArray({"foo", "bar", "baz"}));
}
TEST_F(ProcessStatsDataSourceTest, DontRescanCachedPIDsAndTIDs) {
+ // assertion helpers
+ auto expected_process = [](int pid) {
+ return [pid](protos::ProcessTree::Process process) {
+ return process.pid() == pid && process.cmdline_size() > 0 &&
+ process.cmdline(0) == "proc_" + std::to_string(pid);
+ };
+ };
+ auto expected_thread = [](int tid) {
+ return [tid](protos::ProcessTree::Thread thread) {
+ return thread.tid() == tid && thread.tgid() == tid / 10 * 10 &&
+ thread.name() == "thread_" + std::to_string(tid);
+ };
+ };
+
DataSourceConfig config;
config.mutable_process_stats_config()->set_record_thread_names(true);
auto data_source = GetProcessStatsDataSource(config);
@@ -107,25 +123,163 @@ TEST_F(ProcessStatsDataSourceTest, DontRescanCachedPIDsAndTIDs) {
data_source->OnPids({30});
data_source->OnPids({10, 30, 10, 31, 32});
- std::unique_ptr<protos::TracePacket> packet = writer_raw_->ParseProto();
- ASSERT_TRUE(packet->has_process_tree());
- const auto& proceses = packet->process_tree().processes();
- const auto& threads = packet->process_tree().threads();
- ASSERT_EQ(proceses.size(), 3);
- int tid_idx = 0;
- for (int pid_idx = 0; pid_idx < 3; pid_idx++) {
- int pid = (pid_idx + 1) * 10;
- std::string proc_name = "proc_" + std::to_string(pid);
- ASSERT_EQ(proceses.Get(pid_idx).pid(), pid);
- ASSERT_EQ(proceses.Get(pid_idx).cmdline().Get(0), proc_name);
- for (int tid = pid + 1; tid < pid + 3; tid++, tid_idx++) {
- ASSERT_EQ(threads.Get(tid_idx).tid(), tid);
- ASSERT_EQ(threads.Get(tid_idx).tgid(), pid);
- ASSERT_EQ(threads.Get(tid_idx).name(), "thread_" + std::to_string(tid));
- }
+ // check written contents
+ std::vector<protos::TracePacket> trace = writer_raw_->GetAllTracePackets();
+ EXPECT_EQ(trace.size(), 3);
+
+ // first packet - two unique processes, four threads
+ auto ps_tree = trace[0].process_tree();
+ EXPECT_THAT(ps_tree.processes(),
+ UnorderedElementsAre(Truly(expected_process(10)),
+ Truly(expected_process(20))));
+ EXPECT_THAT(ps_tree.threads(),
+ UnorderedElementsAre(
+ Truly(expected_thread(11)), Truly(expected_thread(12)),
+ Truly(expected_thread(21)), Truly(expected_thread(22))));
+
+ // second packet - one new process
+ ps_tree = trace[1].process_tree();
+ EXPECT_THAT(ps_tree.processes(),
+ UnorderedElementsAre(Truly(expected_process(30))));
+ EXPECT_EQ(ps_tree.threads_size(), 0);
+
+ // third packet - two threads that haven't been seen before
+ ps_tree = trace[2].process_tree();
+ EXPECT_EQ(ps_tree.processes_size(), 0);
+ EXPECT_THAT(ps_tree.threads(),
+ UnorderedElementsAre(Truly(expected_thread(31)),
+ Truly(expected_thread(32))));
+}
+
+TEST_F(ProcessStatsDataSourceTest, IncrementalStateClear) {
+ auto data_source = GetProcessStatsDataSource(DataSourceConfig());
+ EXPECT_CALL(*data_source, ReadProcPidFile(42, "status"))
+ .WillOnce(Return("Name: foo\nTgid:\t42\nPid: 42\nPPid: 17\n"));
+ EXPECT_CALL(*data_source, ReadProcPidFile(42, "cmdline"))
+ .WillOnce(Return(std::string("first_cmdline\0", 14)));
+
+ data_source->OnPids({42});
+
+ {
+ std::vector<protos::TracePacket> trace = writer_raw_->GetAllTracePackets();
+ ASSERT_EQ(trace.size(), 1);
+ auto packet = trace[0];
+ // First packet in the trace has no previous state, so the clear marker is
+ // emitted.
+ ASSERT_TRUE(packet.incremental_state_cleared());
+
+ auto ps_tree = packet.process_tree();
+ ASSERT_EQ(ps_tree.processes_size(), 1);
+ ASSERT_EQ(ps_tree.processes(0).pid(), 42);
+ ASSERT_EQ(ps_tree.processes(0).ppid(), 17);
+ ASSERT_THAT(ps_tree.processes(0).cmdline(),
+ ElementsAreArray({"first_cmdline"}));
+ }
+
+ // Look up the same pid, which shouldn't be re-emitted.
+ Mock::VerifyAndClearExpectations(data_source.get());
+ EXPECT_CALL(*data_source, ReadProcPidFile(42, "status")).Times(0);
+ EXPECT_CALL(*data_source, ReadProcPidFile(42, "cmdline")).Times(0);
+
+ data_source->OnPids({42});
+
+ {
+ std::vector<protos::TracePacket> trace = writer_raw_->GetAllTracePackets();
+ ASSERT_EQ(trace.size(), 1);
+ }
+
+ // Invalidate incremental state, and look up the same pid again, which should
+ // re-emit the proc tree info.
+ Mock::VerifyAndClearExpectations(data_source.get());
+ EXPECT_CALL(*data_source, ReadProcPidFile(42, "status"))
+ .WillOnce(Return("Name: foo\nTgid:\t42\nPid: 42\nPPid: 18\n"));
+ EXPECT_CALL(*data_source, ReadProcPidFile(42, "cmdline"))
+ .WillOnce(Return(std::string("second_cmdline\0", 15)));
+
+ data_source->ClearIncrementalState();
+ data_source->OnPids({42});
+
+ {
+ // Second packet with new proc information.
+ std::vector<protos::TracePacket> trace = writer_raw_->GetAllTracePackets();
+ ASSERT_EQ(trace.size(), 2);
+ auto packet = trace[1];
+ ASSERT_TRUE(packet.incremental_state_cleared());
+
+ auto ps_tree = packet.process_tree();
+ ASSERT_EQ(ps_tree.processes_size(), 1);
+ ASSERT_EQ(ps_tree.processes(0).pid(), 42);
+ ASSERT_EQ(ps_tree.processes(0).ppid(), 18);
+ ASSERT_THAT(ps_tree.processes(0).cmdline(),
+ ElementsAreArray({"second_cmdline"}));
}
}
+TEST_F(ProcessStatsDataSourceTest, RenamePids) {
+ // assertion helpers
+ auto expected_old_process = [](int pid) {
+ return [pid](protos::ProcessTree::Process process) {
+ return process.pid() == pid && process.cmdline_size() > 0 &&
+ process.cmdline(0) == "proc_" + std::to_string(pid);
+ };
+ };
+ auto expected_new_process = [](int pid) {
+ return [pid](protos::ProcessTree::Process process) {
+ return process.pid() == pid && process.cmdline_size() > 0 &&
+ process.cmdline(0) == "new_" + std::to_string(pid);
+ };
+ };
+
+ DataSourceConfig config;
+ auto data_source = GetProcessStatsDataSource(config);
+ for (int p : {10, 20}) {
+ EXPECT_CALL(*data_source, ReadProcPidFile(p, "status"))
+ .WillRepeatedly(Invoke([](int32_t pid, const std::string&) {
+ return "Name: \tthread_" + std::to_string(pid) +
+ "\nTgid: " + std::to_string(pid) +
+ "\nPid: " + std::to_string(pid) + "\nPPid: 1\n";
+ }));
+
+ std::string old_proc_name = "proc_" + std::to_string(p);
+ old_proc_name.resize(old_proc_name.size() + 1); // Add a trailing \0.
+
+ std::string new_proc_name = "new_" + std::to_string(p);
+ new_proc_name.resize(new_proc_name.size() + 1); // Add a trailing \0.
+ EXPECT_CALL(*data_source, ReadProcPidFile(p, "cmdline"))
+ .WillOnce(Return(old_proc_name))
+ .WillOnce(Return(new_proc_name));
+ }
+
+ data_source->OnPids({10, 20});
+ data_source->OnRenamePids({10});
+ data_source->OnPids({10, 20});
+ data_source->OnRenamePids({20});
+ data_source->OnPids({10, 20});
+
+ // check written contents
+ std::vector<protos::TracePacket> trace = writer_raw_->GetAllTracePackets();
+ EXPECT_EQ(trace.size(), 3);
+
+ // first packet - two unique processes
+ auto ps_tree = trace[0].process_tree();
+ EXPECT_THAT(ps_tree.processes(),
+ UnorderedElementsAre(Truly(expected_old_process(10)),
+ Truly(expected_old_process(20))));
+ EXPECT_EQ(ps_tree.threads_size(), 0);
+
+ // second packet - one new process
+ ps_tree = trace[1].process_tree();
+ EXPECT_THAT(ps_tree.processes(),
+ UnorderedElementsAre(Truly(expected_new_process(10))));
+ EXPECT_EQ(ps_tree.threads_size(), 0);
+
+ // third packet - two threads that haven't been seen before
+ ps_tree = trace[2].process_tree();
+ EXPECT_THAT(ps_tree.processes(),
+ UnorderedElementsAre(Truly(expected_new_process(20))));
+ EXPECT_EQ(ps_tree.threads_size(), 0);
+}
+
TEST_F(ProcessStatsDataSourceTest, ProcessStats) {
DataSourceConfig cfg;
cfg.mutable_process_stats_config()->set_proc_stats_poll_ms(1);
@@ -178,14 +332,16 @@ TEST_F(ProcessStatsDataSourceTest, ProcessStats) {
task_runner_.RunUntilCheckpoint("all_done");
data_source->Flush(1 /* FlushRequestId */, []() {});
- // |packet| will contain the merge of all kNumIter packets written.
- std::unique_ptr<protos::TracePacket> packet = writer_raw_->ParseProto();
- ASSERT_TRUE(packet);
- ASSERT_TRUE(packet->has_process_stats());
- const auto& ps_stats = packet->process_stats();
- ASSERT_EQ(ps_stats.processes_size(), kNumIters * base::ArraySize(kPids));
+ std::vector<protos::ProcessStats::Process> processes;
+ std::vector<protos::TracePacket> trace = writer_raw_->GetAllTracePackets();
+ for (const auto& packet : trace) {
+ for (const auto& process : packet.process_stats().processes()) {
+ processes.push_back(process);
+ }
+ }
+ ASSERT_EQ(processes.size(), kNumIters * base::ArraySize(kPids));
iter = 0;
- for (const auto& proc_counters : ps_stats.processes()) {
+ for (const auto& proc_counters : processes) {
int32_t pid = proc_counters.pid();
ASSERT_EQ(proc_counters.vm_size_kb(), pid * 100 + iter * 10 + 1);
ASSERT_EQ(proc_counters.vm_rss_kb(), pid * 100 + iter * 10 + 2);
@@ -243,17 +399,19 @@ TEST_F(ProcessStatsDataSourceTest, CacheProcessStats) {
task_runner_.RunUntilCheckpoint("all_done");
data_source->Flush(1 /* FlushRequestId */, []() {});
- std::unique_ptr<protos::TracePacket> packet = writer_raw_->ParseProto();
- ASSERT_TRUE(packet);
- ASSERT_TRUE(packet->has_process_stats());
- const auto& ps_stats = packet->process_stats();
- ASSERT_EQ(ps_stats.processes_size(), 2);
-
+ std::vector<protos::ProcessStats::Process> processes;
+ std::vector<protos::TracePacket> trace = writer_raw_->GetAllTracePackets();
+ for (const auto& packet : trace) {
+ for (const auto& process : packet.process_stats().processes()) {
+ processes.push_back(process);
+ }
+ }
// We should get two counter events because:
// a) emissions happen at 0ms, 105ms, 210ms, 315ms
// b) clear events happen at 220ms, 440ms...
// Therefore, we should see the emissions at 0ms and 315ms.
- for (const auto& proc_counters : ps_stats.processes()) {
+ ASSERT_EQ(processes.size(), 2);
+ for (const auto& proc_counters : processes) {
ASSERT_EQ(proc_counters.pid(), kPid);
ASSERT_EQ(proc_counters.vm_size_kb(), kPid * 100 + 1);
ASSERT_EQ(proc_counters.vm_rss_kb(), kPid * 100 + 2);
diff --git a/src/traced/service/lazy_producer.h b/src/traced/service/lazy_producer.h
index 85510df8e..541b5baef 100644
--- a/src/traced/service/lazy_producer.h
+++ b/src/traced/service/lazy_producer.h
@@ -47,6 +47,8 @@ class LazyProducer : public Producer {
size_t) override {
endpoint_->NotifyFlushComplete(flush_id);
}
+ void ClearIncrementalState(const DataSourceInstanceID* /*data_source_ids*/,
+ size_t /*num_data_sources*/) override {}
void OnConnect() override;
void SetupDataSource(DataSourceInstanceID, const DataSourceConfig&) override;
diff --git a/src/tracing/core/data_source_descriptor.cc b/src/tracing/core/data_source_descriptor.cc
index 96cc87efd..1ab58d45b 100644
--- a/src/tracing/core/data_source_descriptor.cc
+++ b/src/tracing/core/data_source_descriptor.cc
@@ -47,7 +47,9 @@ DataSourceDescriptor& DataSourceDescriptor::operator=(DataSourceDescriptor&&) =
bool DataSourceDescriptor::operator==(const DataSourceDescriptor& other) const {
return (name_ == other.name_) &&
(will_notify_on_stop_ == other.will_notify_on_stop_) &&
- (will_notify_on_start_ == other.will_notify_on_start_);
+ (will_notify_on_start_ == other.will_notify_on_start_) &&
+ (handles_incremental_state_clear_ ==
+ other.handles_incremental_state_clear_);
}
#pragma GCC diagnostic pop
@@ -67,6 +69,13 @@ void DataSourceDescriptor::FromProto(
"size mismatch");
will_notify_on_start_ = static_cast<decltype(will_notify_on_start_)>(
proto.will_notify_on_start());
+
+ static_assert(sizeof(handles_incremental_state_clear_) ==
+ sizeof(proto.handles_incremental_state_clear()),
+ "size mismatch");
+ handles_incremental_state_clear_ =
+ static_cast<decltype(handles_incremental_state_clear_)>(
+ proto.handles_incremental_state_clear());
unknown_fields_ = proto.unknown_fields();
}
@@ -90,6 +99,13 @@ void DataSourceDescriptor::ToProto(
proto->set_will_notify_on_start(
static_cast<decltype(proto->will_notify_on_start())>(
will_notify_on_start_));
+
+ static_assert(sizeof(handles_incremental_state_clear_) ==
+ sizeof(proto->handles_incremental_state_clear()),
+ "size mismatch");
+ proto->set_handles_incremental_state_clear(
+ static_cast<decltype(proto->handles_incremental_state_clear())>(
+ handles_incremental_state_clear_));
*(proto->mutable_unknown_fields()) = unknown_fields_;
}
diff --git a/src/tracing/core/trace_buffer.h b/src/tracing/core/trace_buffer.h
index d86037a25..35bd5fb81 100644
--- a/src/tracing/core/trace_buffer.h
+++ b/src/tracing/core/trace_buffer.h
@@ -27,6 +27,7 @@
#include "perfetto/base/logging.h"
#include "perfetto/base/paged_memory.h"
+#include "perfetto/base/thread_annotations.h"
#include "perfetto/tracing/core/basic_types.h"
#include "perfetto/tracing/core/slice.h"
#include "perfetto/tracing/core/trace_stats.h"
@@ -586,6 +587,16 @@ class TraceBuffer {
PERFETTO_CHECK(wptr + sizeof(record) + size <= end());
memcpy(wptr, &record, sizeof(record));
if (PERFETTO_LIKELY(src)) {
+ // If the producer modifies the data in the shared memory buffer while we
+ // are copying it to the central buffer, TSAN will (rightfully) flag that
+ // as a race. However the entire purpose of copying the data into the
+ // central buffer is that we can validate it without worrying that the
+ // producer changes it from under our feet, so this race is benign. The
+ // alternative would be to try computing which part of the buffer is safe
+ // to read (assuming a well-behaving client), but the risk of introducing
+ // a bug that way outweighs the benefit.
+ PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(
+ src, size, "Benign race when copying chunk from shared memory.");
memcpy(wptr + sizeof(record), src, size);
} else {
PERFETTO_DCHECK(size == record.size - sizeof(record));
diff --git a/src/tracing/core/trace_config.cc b/src/tracing/core/trace_config.cc
index 54ce848f8..866b2f3ec 100644
--- a/src/tracing/core/trace_config.cc
+++ b/src/tracing/core/trace_config.cc
@@ -44,6 +44,7 @@ TraceConfig& TraceConfig::operator=(TraceConfig&&) = default;
bool TraceConfig::operator==(const TraceConfig& other) const {
return (buffers_ == other.buffers_) &&
(data_sources_ == other.data_sources_) &&
+ (builtin_data_sources_ == other.builtin_data_sources_) &&
(duration_ms_ == other.duration_ms_) &&
(enable_extra_guardrails_ == other.enable_extra_guardrails_) &&
(lockdown_mode_ == other.lockdown_mode_) &&
@@ -56,11 +57,12 @@ bool TraceConfig::operator==(const TraceConfig& other) const {
(deferred_start_ == other.deferred_start_) &&
(flush_period_ms_ == other.flush_period_ms_) &&
(flush_timeout_ms_ == other.flush_timeout_ms_) &&
- (disable_clock_snapshotting_ == other.disable_clock_snapshotting_) &&
(notify_traceur_ == other.notify_traceur_) &&
(trigger_config_ == other.trigger_config_) &&
(activate_triggers_ == other.activate_triggers_) &&
- (allow_user_build_tracing_ == other.allow_user_build_tracing_);
+ (incremental_state_config_ == other.incremental_state_config_) &&
+ (allow_user_build_tracing_ == other.allow_user_build_tracing_) &&
+ (unique_session_name_ == other.unique_session_name_);
}
#pragma GCC diagnostic pop
@@ -77,6 +79,8 @@ void TraceConfig::FromProto(const perfetto::protos::TraceConfig& proto) {
data_sources_.back().FromProto(field);
}
+ builtin_data_sources_.FromProto(proto.builtin_data_sources());
+
static_assert(sizeof(duration_ms_) == sizeof(proto.duration_ms()),
"size mismatch");
duration_ms_ = static_cast<decltype(duration_ms_)>(proto.duration_ms());
@@ -133,13 +137,6 @@ void TraceConfig::FromProto(const perfetto::protos::TraceConfig& proto) {
flush_timeout_ms_ =
static_cast<decltype(flush_timeout_ms_)>(proto.flush_timeout_ms());
- static_assert(sizeof(disable_clock_snapshotting_) ==
- sizeof(proto.disable_clock_snapshotting()),
- "size mismatch");
- disable_clock_snapshotting_ =
- static_cast<decltype(disable_clock_snapshotting_)>(
- proto.disable_clock_snapshotting());
-
static_assert(sizeof(notify_traceur_) == sizeof(proto.notify_traceur()),
"size mismatch");
notify_traceur_ =
@@ -157,11 +154,19 @@ void TraceConfig::FromProto(const perfetto::protos::TraceConfig& proto) {
static_cast<decltype(activate_triggers_)::value_type>(field);
}
+ incremental_state_config_.FromProto(proto.incremental_state_config());
+
static_assert(sizeof(allow_user_build_tracing_) ==
sizeof(proto.allow_user_build_tracing()),
"size mismatch");
allow_user_build_tracing_ = static_cast<decltype(allow_user_build_tracing_)>(
proto.allow_user_build_tracing());
+
+ static_assert(
+ sizeof(unique_session_name_) == sizeof(proto.unique_session_name()),
+ "size mismatch");
+ unique_session_name_ =
+ static_cast<decltype(unique_session_name_)>(proto.unique_session_name());
unknown_fields_ = proto.unknown_fields();
}
@@ -178,6 +183,8 @@ void TraceConfig::ToProto(perfetto::protos::TraceConfig* proto) const {
it.ToProto(entry);
}
+ builtin_data_sources_.ToProto(proto->mutable_builtin_data_sources());
+
static_assert(sizeof(duration_ms_) == sizeof(proto->duration_ms()),
"size mismatch");
proto->set_duration_ms(
@@ -238,13 +245,6 @@ void TraceConfig::ToProto(perfetto::protos::TraceConfig* proto) const {
proto->set_flush_timeout_ms(
static_cast<decltype(proto->flush_timeout_ms())>(flush_timeout_ms_));
- static_assert(sizeof(disable_clock_snapshotting_) ==
- sizeof(proto->disable_clock_snapshotting()),
- "size mismatch");
- proto->set_disable_clock_snapshotting(
- static_cast<decltype(proto->disable_clock_snapshotting())>(
- disable_clock_snapshotting_));
-
static_assert(sizeof(notify_traceur_) == sizeof(proto->notify_traceur()),
"size mismatch");
proto->set_notify_traceur(
@@ -259,12 +259,21 @@ void TraceConfig::ToProto(perfetto::protos::TraceConfig* proto) const {
"size mismatch");
}
+ incremental_state_config_.ToProto(proto->mutable_incremental_state_config());
+
static_assert(sizeof(allow_user_build_tracing_) ==
sizeof(proto->allow_user_build_tracing()),
"size mismatch");
proto->set_allow_user_build_tracing(
static_cast<decltype(proto->allow_user_build_tracing())>(
allow_user_build_tracing_));
+
+ static_assert(
+ sizeof(unique_session_name_) == sizeof(proto->unique_session_name()),
+ "size mismatch");
+ proto->set_unique_session_name(
+ static_cast<decltype(proto->unique_session_name())>(
+ unique_session_name_));
*(proto->mutable_unknown_fields()) = unknown_fields_;
}
@@ -362,6 +371,77 @@ void TraceConfig::DataSource::ToProto(
*(proto->mutable_unknown_fields()) = unknown_fields_;
}
+TraceConfig::BuiltinDataSource::BuiltinDataSource() = default;
+TraceConfig::BuiltinDataSource::~BuiltinDataSource() = default;
+TraceConfig::BuiltinDataSource::BuiltinDataSource(
+ const TraceConfig::BuiltinDataSource&) = default;
+TraceConfig::BuiltinDataSource& TraceConfig::BuiltinDataSource::operator=(
+ const TraceConfig::BuiltinDataSource&) = default;
+TraceConfig::BuiltinDataSource::BuiltinDataSource(
+ TraceConfig::BuiltinDataSource&&) noexcept = default;
+TraceConfig::BuiltinDataSource& TraceConfig::BuiltinDataSource::operator=(
+ TraceConfig::BuiltinDataSource&&) = default;
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+bool TraceConfig::BuiltinDataSource::operator==(
+ const TraceConfig::BuiltinDataSource& other) const {
+ return (disable_clock_snapshotting_ == other.disable_clock_snapshotting_) &&
+ (disable_trace_config_ == other.disable_trace_config_) &&
+ (disable_system_info_ == other.disable_system_info_);
+}
+#pragma GCC diagnostic pop
+
+void TraceConfig::BuiltinDataSource::FromProto(
+ const perfetto::protos::TraceConfig_BuiltinDataSource& proto) {
+ static_assert(sizeof(disable_clock_snapshotting_) ==
+ sizeof(proto.disable_clock_snapshotting()),
+ "size mismatch");
+ disable_clock_snapshotting_ =
+ static_cast<decltype(disable_clock_snapshotting_)>(
+ proto.disable_clock_snapshotting());
+
+ static_assert(
+ sizeof(disable_trace_config_) == sizeof(proto.disable_trace_config()),
+ "size mismatch");
+ disable_trace_config_ = static_cast<decltype(disable_trace_config_)>(
+ proto.disable_trace_config());
+
+ static_assert(
+ sizeof(disable_system_info_) == sizeof(proto.disable_system_info()),
+ "size mismatch");
+ disable_system_info_ =
+ static_cast<decltype(disable_system_info_)>(proto.disable_system_info());
+ unknown_fields_ = proto.unknown_fields();
+}
+
+void TraceConfig::BuiltinDataSource::ToProto(
+ perfetto::protos::TraceConfig_BuiltinDataSource* proto) const {
+ proto->Clear();
+
+ static_assert(sizeof(disable_clock_snapshotting_) ==
+ sizeof(proto->disable_clock_snapshotting()),
+ "size mismatch");
+ proto->set_disable_clock_snapshotting(
+ static_cast<decltype(proto->disable_clock_snapshotting())>(
+ disable_clock_snapshotting_));
+
+ static_assert(
+ sizeof(disable_trace_config_) == sizeof(proto->disable_trace_config()),
+ "size mismatch");
+ proto->set_disable_trace_config(
+ static_cast<decltype(proto->disable_trace_config())>(
+ disable_trace_config_));
+
+ static_assert(
+ sizeof(disable_system_info_) == sizeof(proto->disable_system_info()),
+ "size mismatch");
+ proto->set_disable_system_info(
+ static_cast<decltype(proto->disable_system_info())>(
+ disable_system_info_));
+ *(proto->mutable_unknown_fields()) = unknown_fields_;
+}
+
TraceConfig::ProducerConfig::ProducerConfig() = default;
TraceConfig::ProducerConfig::~ProducerConfig() = default;
TraceConfig::ProducerConfig::ProducerConfig(
@@ -669,4 +749,43 @@ void TraceConfig::TriggerConfig::Trigger::ToProto(
*(proto->mutable_unknown_fields()) = unknown_fields_;
}
+TraceConfig::IncrementalStateConfig::IncrementalStateConfig() = default;
+TraceConfig::IncrementalStateConfig::~IncrementalStateConfig() = default;
+TraceConfig::IncrementalStateConfig::IncrementalStateConfig(
+ const TraceConfig::IncrementalStateConfig&) = default;
+TraceConfig::IncrementalStateConfig& TraceConfig::IncrementalStateConfig::
+operator=(const TraceConfig::IncrementalStateConfig&) = default;
+TraceConfig::IncrementalStateConfig::IncrementalStateConfig(
+ TraceConfig::IncrementalStateConfig&&) noexcept = default;
+TraceConfig::IncrementalStateConfig& TraceConfig::IncrementalStateConfig::
+operator=(TraceConfig::IncrementalStateConfig&&) = default;
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+bool TraceConfig::IncrementalStateConfig::operator==(
+ const TraceConfig::IncrementalStateConfig& other) const {
+ return (clear_period_ms_ == other.clear_period_ms_);
+}
+#pragma GCC diagnostic pop
+
+void TraceConfig::IncrementalStateConfig::FromProto(
+ const perfetto::protos::TraceConfig_IncrementalStateConfig& proto) {
+ static_assert(sizeof(clear_period_ms_) == sizeof(proto.clear_period_ms()),
+ "size mismatch");
+ clear_period_ms_ =
+ static_cast<decltype(clear_period_ms_)>(proto.clear_period_ms());
+ unknown_fields_ = proto.unknown_fields();
+}
+
+void TraceConfig::IncrementalStateConfig::ToProto(
+ perfetto::protos::TraceConfig_IncrementalStateConfig* proto) const {
+ proto->Clear();
+
+ static_assert(sizeof(clear_period_ms_) == sizeof(proto->clear_period_ms()),
+ "size mismatch");
+ proto->set_clear_period_ms(
+ static_cast<decltype(proto->clear_period_ms())>(clear_period_ms_));
+ *(proto->mutable_unknown_fields()) = unknown_fields_;
+}
+
} // namespace perfetto
diff --git a/src/tracing/core/trace_writer_for_testing.cc b/src/tracing/core/trace_writer_for_testing.cc
index b77a19d14..6cfb559ea 100644
--- a/src/tracing/core/trace_writer_for_testing.cc
+++ b/src/tracing/core/trace_writer_for_testing.cc
@@ -18,9 +18,10 @@
#include "perfetto/base/logging.h"
#include "perfetto/base/utils.h"
-
#include "perfetto/protozero/message.h"
-
+#include "perfetto/trace/trace.pb.h"
+#include "perfetto/trace/trace.pbzero.h"
+#include "perfetto/trace/trace_packet.pb.h"
#include "perfetto/trace/trace_packet.pbzero.h"
namespace perfetto {
@@ -44,12 +45,28 @@ void TraceWriterForTesting::Flush(std::function<void()> callback) {
callback();
}
-std::unique_ptr<protos::TracePacket> TraceWriterForTesting::ParseProto() {
+std::vector<protos::TracePacket> TraceWriterForTesting::GetAllTracePackets() {
PERFETTO_CHECK(cur_packet_->is_finalized());
- auto packet = std::unique_ptr<protos::TracePacket>(new protos::TracePacket());
+
+ auto trace = protos::Trace();
std::vector<uint8_t> buffer = delegate_.StitchSlices();
- if (!packet->ParseFromArray(buffer.data(), static_cast<int>(buffer.size())))
- return nullptr;
+ if (!trace.ParseFromArray(buffer.data(), static_cast<int>(buffer.size())))
+ return {};
+
+ std::vector<protos::TracePacket> ret;
+ for (const auto& packet : trace.packet()) {
+ ret.emplace_back(packet);
+ }
+ return ret;
+}
+
+std::unique_ptr<protos::TracePacket> TraceWriterForTesting::ParseProto() {
+ PERFETTO_CHECK(cur_packet_->is_finalized());
+
+ auto trace = GetAllTracePackets();
+ PERFETTO_CHECK(!trace.empty());
+ auto packet =
+ std::unique_ptr<protos::TracePacket>(new protos::TracePacket(trace[0]));
return packet;
}
@@ -59,7 +76,22 @@ TraceWriterForTesting::NewTracePacket() {
// finalized the previous packet.
PERFETTO_DCHECK(cur_packet_->is_finalized());
cur_packet_->Reset(&stream_);
- return TraceWriter::TracePacketHandle(cur_packet_.get());
+
+ // Instead of storing the contents of the TracePacket directly in the backing
+ // buffer like the real trace writers, we prepend the proto preamble to make
+ // the buffer contents parsable as a sequence of TracePacket protos.
+
+ uint8_t data[protozero::proto_utils::kMaxTagEncodedSize];
+ uint8_t* data_end = protozero::proto_utils::WriteVarInt(
+ protozero::proto_utils::MakeTagLengthDelimited(
+ protos::pbzero::Trace::kPacketFieldNumber),
+ data);
+ stream_.WriteBytes(data, static_cast<uint32_t>(data_end - data));
+
+ auto packet = TraceWriter::TracePacketHandle(cur_packet_.get());
+ packet->set_size_field(
+ stream_.ReserveBytes(protozero::proto_utils::kMessageLengthFieldSize));
+ return packet;
}
WriterID TraceWriterForTesting::writer_id() const {
diff --git a/src/tracing/core/trace_writer_for_testing.h b/src/tracing/core/trace_writer_for_testing.h
index 4475d6dc9..f7a1a883b 100644
--- a/src/tracing/core/trace_writer_for_testing.h
+++ b/src/tracing/core/trace_writer_for_testing.h
@@ -16,6 +16,8 @@
#ifndef SRC_TRACING_CORE_TRACE_WRITER_FOR_TESTING_H_
#define SRC_TRACING_CORE_TRACE_WRITER_FOR_TESTING_H_
+#include <vector>
+
#include "perfetto/protozero/message_handle.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
#include "perfetto/trace/trace_packet.pb.h"
@@ -28,7 +30,6 @@ namespace perfetto {
// See //include/perfetto/tracing/core/trace_writer.h for docs.
class TraceWriterForTesting : public TraceWriter {
public:
- // TraceWriterForTesting(const protozero::ScatteredHeapBuffer& delegate);
TraceWriterForTesting();
~TraceWriterForTesting() override;
@@ -37,6 +38,8 @@ class TraceWriterForTesting : public TraceWriter {
TracePacketHandle NewTracePacket() override;
void Flush(std::function<void()> callback = {}) override;
+ std::vector<protos::TracePacket> GetAllTracePackets();
+ // TODO(rsavitski): rewrite as "get only packet".
std::unique_ptr<protos::TracePacket> ParseProto();
WriterID writer_id() const override;
diff --git a/src/tracing/core/tracing_service_impl.cc b/src/tracing/core/tracing_service_impl.cc
index 11b1ef157..c6aac42c2 100644
--- a/src/tracing/core/tracing_service_impl.cc
+++ b/src/tracing/core/tracing_service_impl.cc
@@ -362,6 +362,18 @@ bool TracingServiceImpl::EnableTracing(ConsumerEndpointImpl* consumer,
return false;
}
+ if (!cfg.unique_session_name().empty()) {
+ const std::string& name = cfg.unique_session_name();
+ for (auto& kv : tracing_sessions_) {
+ if (kv.second.config.unique_session_name() == name) {
+ PERFETTO_ELOG(
+ "A trace wtih this unique session name (%s) already exists",
+ name.c_str());
+ return false;
+ }
+ }
+ }
+
// TODO(primiano): This is a workaround to prevent that a producer gets stuck
// in a state where it stalls by design by having more TraceWriterImpl
// instances than free pages in the buffer. This is really a bug in
@@ -642,6 +654,12 @@ bool TracingServiceImpl::StartTracing(TracingSessionID tsid) {
tracing_session->state = TracingSession::STARTED;
+ if (!tracing_session->config.builtin_data_sources()
+ .disable_clock_snapshotting()) {
+ SnapshotClocks(&tracing_session->initial_clock_snapshot_,
+ /*set_root_timestamp=*/true);
+ }
+
// Trigger delayed task if the trace is time limited.
const uint32_t trace_duration_ms = tracing_session->config.duration_ms();
if (trace_duration_ms > 0) {
@@ -684,6 +702,12 @@ bool TracingServiceImpl::StartTracing(TracingSessionID tsid) {
if (tracing_session->config.flush_period_ms())
PeriodicFlushTask(tsid, /*post_next_only=*/true);
+ // Start the periodic incremental state clear tasks if the config specified a
+ // period.
+ if (tracing_session->config.incremental_state_config().clear_period_ms()) {
+ PeriodicClearIncrementalStateTask(tsid, /*post_next_only=*/true);
+ }
+
for (auto& kv : tracing_session->data_source_instances) {
ProducerID producer_id = kv.first;
DataSourceInstance& data_source = kv.second;
@@ -1046,7 +1070,7 @@ void TracingServiceImpl::Flush(TracingSessionID tsid,
}
// If there are no producers to flush (realistically this happens only in
- // some tests) fire OnFlushTimeout() straight away, without waiting.
+ // some tests) fire OnFlushTimeout() straight away, without waiting.
if (flush_map.empty())
timeout_ms = 0;
@@ -1280,13 +1304,60 @@ void TracingServiceImpl::PeriodicFlushTask(TracingSessionID tsid,
if (post_next_only)
return;
- PERFETTO_DLOG("Triggering periodic flush for %" PRIu64, tsid);
+ PERFETTO_DLOG("Triggering periodic flush for trace session %" PRIu64, tsid);
Flush(tsid, 0, [](bool success) {
if (!success)
PERFETTO_ELOG("Periodic flush timed out");
});
}
+void TracingServiceImpl::PeriodicClearIncrementalStateTask(
+ TracingSessionID tsid,
+ bool post_next_only) {
+ PERFETTO_DCHECK_THREAD(thread_checker_);
+ TracingSession* tracing_session = GetTracingSession(tsid);
+ if (!tracing_session || tracing_session->state != TracingSession::STARTED)
+ return;
+
+ uint32_t clear_period_ms =
+ tracing_session->config.incremental_state_config().clear_period_ms();
+ auto weak_this = weak_ptr_factory_.GetWeakPtr();
+ task_runner_->PostDelayedTask(
+ [weak_this, tsid] {
+ if (weak_this)
+ weak_this->PeriodicClearIncrementalStateTask(
+ tsid, /*post_next_only=*/false);
+ },
+ clear_period_ms - (base::GetWallTimeMs().count() % clear_period_ms));
+
+ if (post_next_only)
+ return;
+
+ PERFETTO_DLOG(
+ "Performing periodic incremental state clear for trace session %" PRIu64,
+ tsid);
+
+ // Queue the IPCs to producers with active data sources that opted in.
+ std::map<ProducerID, std::vector<DataSourceInstanceID>> clear_map;
+ 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)
+ clear_map[producer_id].push_back(data_source.instance_id);
+ }
+
+ for (const auto& kv : clear_map) {
+ ProducerID producer_id = kv.first;
+ const std::vector<DataSourceInstanceID>& data_sources = kv.second;
+ ProducerEndpointImpl* producer = GetProducer(producer_id);
+ if (!producer) {
+ PERFETTO_DFATAL("Producer does not exist.");
+ continue;
+ }
+ producer->ClearIncrementalState(data_sources);
+ }
+}
+
// 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).
@@ -1326,25 +1397,38 @@ void TracingServiceImpl::ReadBuffers(TracingSessionID tsid,
// 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.
- PERFETTO_DFATAL("Consumer trying to read from write_to_file session.");
+ PERFETTO_DFATAL("Consumer trying to read from write_into_file session.");
return;
}
std::vector<TracePacket> packets;
packets.reserve(1024); // Just an educated guess to avoid trivial expansions.
+ std::move(tracing_session->initial_clock_snapshot_.begin(),
+ tracing_session->initial_clock_snapshot_.end(),
+ std::back_inserter(packets));
+ tracing_session->initial_clock_snapshot_.clear();
+
base::TimeMillis now = base::GetWallTimeMs();
if (now >= tracing_session->last_snapshot_time + kSnapshotsInterval) {
tracing_session->last_snapshot_time = now;
SnapshotSyncMarker(&packets);
SnapshotStats(tracing_session, &packets);
- if (!tracing_session->config.disable_clock_snapshotting())
- SnapshotClocks(&packets);
+ if (!tracing_session->config.builtin_data_sources()
+ .disable_clock_snapshotting()) {
+ // We don't want to put a root timestamp in this snapshot as the packet
+ // may be very out of order with respect to the actual trace packets
+ // since consuming the trace may happen at any point after it starts.
+ SnapshotClocks(&packets, /*set_root_timestamp=*/false);
+ }
+ }
+ if (!tracing_session->config.builtin_data_sources().disable_trace_config()) {
+ MaybeEmitTraceConfig(tracing_session, &packets);
+ MaybeEmitReceivedTriggers(tracing_session, &packets);
}
- MaybeEmitTraceConfig(tracing_session, &packets);
- MaybeEmitSystemInfo(tracing_session, &packets);
- MaybeEmitReceivedTriggers(tracing_session, &packets);
+ if (!tracing_session->config.builtin_data_sources().disable_system_info())
+ MaybeEmitSystemInfo(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|).
@@ -1707,11 +1791,13 @@ TracingServiceImpl::DataSourceInstance* TracingServiceImpl::SetupDataSource(
auto insert_iter = tracing_session->data_source_instances.emplace(
std::piecewise_construct, //
std::forward_as_tuple(producer->id_),
- std::forward_as_tuple(inst_id,
- cfg_data_source.config(), // Deliberate copy.
- data_source.descriptor.name(),
- data_source.descriptor.will_notify_on_start(),
- data_source.descriptor.will_notify_on_stop()));
+ std::forward_as_tuple(
+ inst_id,
+ cfg_data_source.config(), // Deliberate copy.
+ data_source.descriptor.name(),
+ data_source.descriptor.will_notify_on_start(),
+ data_source.descriptor.will_notify_on_stop(),
+ data_source.descriptor.handles_incremental_state_clear()));
DataSourceInstance* ds_instance = &insert_iter->second;
// New data source instance starts out in CONFIGURED state.
@@ -2000,7 +2086,8 @@ void TracingServiceImpl::SnapshotSyncMarker(std::vector<TracePacket>* packets) {
packets->back().AddSlice(&sync_marker_packet_[0], sync_marker_packet_size_);
}
-void TracingServiceImpl::SnapshotClocks(std::vector<TracePacket>* packets) {
+void TracingServiceImpl::SnapshotClocks(std::vector<TracePacket>* packets,
+ bool set_root_timestamp) {
protos::TrustedPacket packet;
protos::ClockSnapshot* clock_snapshot = packet.mutable_clock_snapshot();
@@ -2036,15 +2123,23 @@ void TracingServiceImpl::SnapshotClocks(std::vector<TracePacket>* packets) {
PERFETTO_DLOG("clock_gettime failed for clock %d", clock.id);
}
for (auto& clock : clocks) {
+ if (set_root_timestamp &&
+ clock.type == protos::ClockSnapshot::Clock::BOOTTIME) {
+ packet.set_timestamp(
+ static_cast<uint64_t>(base::FromPosixTimespec(clock.ts).count()));
+ };
protos::ClockSnapshot::Clock* c = clock_snapshot->add_clocks();
c->set_type(clock.type);
c->set_timestamp(
static_cast<uint64_t>(base::FromPosixTimespec(clock.ts).count()));
}
#else // !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
+ auto wall_time_ns = static_cast<uint64_t>(base::GetWallTimeNs().count());
+ if (set_root_timestamp)
+ packet.set_timestamp(wall_time_ns);
protos::ClockSnapshot::Clock* c = clock_snapshot->add_clocks();
c->set_type(protos::ClockSnapshot::Clock::MONOTONIC);
- c->set_timestamp(static_cast<uint64_t>(base::GetWallTimeNs().count()));
+ c->set_timestamp(wall_time_ns);
#endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
packet.set_trusted_uid(static_cast<int32_t>(uid_));
@@ -2622,6 +2717,18 @@ void TracingServiceImpl::ProducerEndpointImpl::OnFreeBuffers(
allowed_target_buffers_.erase(buffer);
}
+void TracingServiceImpl::ProducerEndpointImpl::ClearIncrementalState(
+ const std::vector<DataSourceInstanceID>& data_sources) {
+ PERFETTO_DCHECK_THREAD(thread_checker_);
+ auto weak_this = weak_ptr_factory_.GetWeakPtr();
+ task_runner_->PostTask([weak_this, data_sources] {
+ if (weak_this) {
+ weak_this->producer_->ClearIncrementalState(data_sources.data(),
+ data_sources.size());
+ }
+ });
+}
+
////////////////////////////////////////////////////////////////////////////////
// TracingServiceImpl::TracingSession implementation
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/tracing/core/tracing_service_impl.h b/src/tracing/core/tracing_service_impl.h
index 474bd7be2..fbae3b607 100644
--- a/src/tracing/core/tracing_service_impl.h
+++ b/src/tracing/core/tracing_service_impl.h
@@ -102,6 +102,7 @@ class TracingServiceImpl : public TracingService {
void StopDataSource(DataSourceInstanceID);
void Flush(FlushRequestID, const std::vector<DataSourceInstanceID>&);
void OnFreeBuffers(const std::vector<BufferID>& target_buffers);
+ void ClearIncrementalState(const std::vector<DataSourceInstanceID>&);
bool is_allowed_target_buffer(BufferID buffer_id) const {
return allowed_target_buffers_.count(buffer_id);
@@ -289,12 +290,15 @@ class TracingServiceImpl : public TracingService {
const DataSourceConfig& cfg,
const std::string& ds_name,
bool notify_on_start,
- bool notify_on_stop)
+ bool notify_on_stop,
+ bool handles_incremental_state_invalidation)
: instance_id(id),
config(cfg),
data_source_name(ds_name),
will_notify_on_start(notify_on_start),
- will_notify_on_stop(notify_on_stop) {}
+ will_notify_on_stop(notify_on_stop),
+ handles_incremental_state_clear(
+ handles_incremental_state_invalidation) {}
DataSourceInstance(const DataSourceInstance&) = delete;
DataSourceInstance& operator=(const DataSourceInstance&) = delete;
@@ -303,6 +307,7 @@ class TracingServiceImpl : public TracingService {
std::string data_source_name;
bool will_notify_on_start;
bool will_notify_on_stop;
+ bool handles_incremental_state_clear;
enum DataSourceInstanceState {
CONFIGURED,
@@ -412,6 +417,9 @@ class TracingServiceImpl : public TracingService {
// List of data source instances that have been enabled on the various
// producers for this tracing session.
+ // TODO(rsavitski): at the time of writing, the map structure is unused
+ // (even when the calling code has a key). This is also an opportunity to
+ // consider an alternative data type, e.g. a map of vectors.
std::multimap<ProducerID, DataSourceInstance> data_source_instances;
// For each Flush(N) request, keeps track of the set of producers for which
@@ -440,6 +448,11 @@ class TracingServiceImpl : public TracingService {
// The number of received triggers we've emitted into the trace output.
size_t num_triggers_emitted_into_trace = 0;
+ // Initial clock snapshot, captured at trace start time (when state goes
+ // to TracingSession::STARTED). Emitted into the trace when the consumer
+ // first begins reading the trace.
+ std::vector<TracePacket> initial_clock_snapshot_;
+
State state = DISABLED;
// If the consumer detached the session, this variable defines the key used
@@ -483,7 +496,7 @@ class TracingServiceImpl : public TracingService {
TracingSession* tracing_session,
DataSourceInstance* instance);
void SnapshotSyncMarker(std::vector<TracePacket>*);
- void SnapshotClocks(std::vector<TracePacket>*);
+ void SnapshotClocks(std::vector<TracePacket>*, bool set_root_timestamp);
void SnapshotStats(TracingSession*, std::vector<TracePacket>*);
TraceStats GetTraceStats(TracingSession* tracing_session);
void MaybeEmitTraceConfig(TracingSession*, std::vector<TracePacket>*);
@@ -498,6 +511,7 @@ class TracingServiceImpl : public TracingService {
bool success);
void ScrapeSharedMemoryBuffers(TracingSession* tracing_session,
ProducerEndpointImpl* producer);
+ void PeriodicClearIncrementalStateTask(TracingSessionID, bool post_next_only);
TraceBuffer* GetBufferByID(BufferID);
void OnStartTriggersTimeout(TracingSessionID tsid);
diff --git a/src/tracing/core/tracing_service_impl_unittest.cc b/src/tracing/core/tracing_service_impl_unittest.cc
index a4c05bdc0..74eeacf01 100644
--- a/src/tracing/core/tracing_service_impl_unittest.cc
+++ b/src/tracing/core/tracing_service_impl_unittest.cc
@@ -186,6 +186,33 @@ class TracingServiceImplTest : public testing::Test {
std::unique_ptr<TracingServiceImpl> svc;
};
+TEST_F(TracingServiceImplTest, AtMostOneConfig) {
+ std::unique_ptr<MockConsumer> consumer_a = CreateMockConsumer();
+ std::unique_ptr<MockConsumer> consumer_b = CreateMockConsumer();
+
+ consumer_a->Connect(svc.get());
+ consumer_b->Connect(svc.get());
+
+ TraceConfig trace_config_a;
+ trace_config_a.add_buffers()->set_size_kb(128);
+ trace_config_a.set_duration_ms(0);
+ trace_config_a.set_unique_session_name("foo");
+
+ TraceConfig trace_config_b;
+ trace_config_b.add_buffers()->set_size_kb(128);
+ trace_config_b.set_duration_ms(0);
+ trace_config_b.set_unique_session_name("foo");
+
+ consumer_a->EnableTracing(trace_config_a);
+ consumer_b->EnableTracing(trace_config_b);
+
+ // This will stop immediately since it has the same unique session name.
+ consumer_b->WaitForTracingDisabled();
+
+ consumer_a->DisableTracing();
+ consumer_a->WaitForTracingDisabled();
+}
+
TEST_F(TracingServiceImplTest, RegisterAndUnregister) {
std::unique_ptr<MockProducer> mock_producer_1 = CreateMockProducer();
std::unique_ptr<MockProducer> mock_producer_2 = CreateMockProducer();
@@ -1315,11 +1342,14 @@ TEST_F(TracingServiceImplTest, WriteIntoFileAndStopOnMaxSize) {
producer->WaitForDataSourceStart("data_source");
// The preamble packets are:
+ // Trace start clocksnapshot
// Config
// SystemInfo
- // 3x unknown
- static const int kNumPreamblePackets = 5;
- static const int kNumTestPackets = 10;
+ // Trace read clocksnapshot
+ // Trace synchronisation
+ // Trace stats
+ static const int kNumPreamblePackets = 6;
+ static const int kNumTestPackets = 9;
static const char kPayload[] = "1234567890abcdef-";
std::unique_ptr<TraceWriter> writer =
@@ -1615,6 +1645,83 @@ TEST_F(TracingServiceImplTest, PeriodicFlush) {
}
}
+TEST_F(TracingServiceImplTest, PeriodicClearIncrementalState) {
+ std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
+ consumer->Connect(svc.get());
+ std::unique_ptr<MockProducer> producer = CreateMockProducer();
+ producer->Connect(svc.get(), "mock_producer");
+
+ // Incremental data source that expects to receive the clear.
+ producer->RegisterDataSource("ds_incremental1", false, false,
+ /*handles_incremental_state_clear=*/true);
+
+ // Incremental data source that expects to receive the clear.
+ producer->RegisterDataSource("ds_incremental2", false, false,
+ /*handles_incremental_state_clear=*/true);
+
+ // Data source that does *not* advertise itself as supporting incremental
+ // state clears.
+ producer->RegisterDataSource("ds_selfcontained", false, false,
+ /*handles_incremental_state_clear=*/false);
+
+ // Incremental data source that is registered, but won't be active within the
+ // test's tracing session.
+ producer->RegisterDataSource("ds_inactive", false, false,
+ /*handles_incremental_state_clear=*/true);
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(128);
+ trace_config.mutable_incremental_state_config()->set_clear_period_ms(1);
+ trace_config.add_data_sources()->mutable_config()->set_name(
+ "ds_selfcontained");
+ trace_config.add_data_sources()->mutable_config()->set_name(
+ "ds_incremental1");
+ trace_config.add_data_sources()->mutable_config()->set_name(
+ "ds_incremental2");
+
+ // note: the mocking is very brittle, and has to assume a specific order of
+ // the data sources' setup/start.
+ consumer->EnableTracing(trace_config);
+ producer->WaitForTracingSetup();
+ producer->WaitForDataSourceSetup("ds_selfcontained");
+ producer->WaitForDataSourceSetup("ds_incremental1");
+ producer->WaitForDataSourceSetup("ds_incremental2");
+ producer->WaitForDataSourceStart("ds_selfcontained");
+ producer->WaitForDataSourceStart("ds_incremental1");
+ producer->WaitForDataSourceStart("ds_incremental2");
+
+ DataSourceInstanceID ds_incremental1 =
+ producer->GetDataSourceInstanceId("ds_incremental1");
+ DataSourceInstanceID ds_incremental2 =
+ producer->GetDataSourceInstanceId("ds_incremental2");
+
+ const size_t kNumClears = 3;
+ std::function<void()> checkpoint =
+ task_runner.CreateCheckpoint("clears_received");
+ std::vector<std::vector<DataSourceInstanceID>> clears_seen;
+ EXPECT_CALL(*producer, ClearIncrementalState(_, _))
+ .WillRepeatedly(Invoke([&clears_seen, &checkpoint](
+ const DataSourceInstanceID* data_source_ids,
+ size_t num_data_sources) {
+ std::vector<DataSourceInstanceID> ds_ids;
+ for (size_t i = 0; i < num_data_sources; i++) {
+ ds_ids.push_back(*data_source_ids++);
+ }
+ clears_seen.push_back(ds_ids);
+ if (clears_seen.size() >= kNumClears)
+ checkpoint();
+ }));
+ task_runner.RunUntilCheckpoint("clears_received");
+
+ consumer->DisableTracing();
+
+ // Assert that the clears were only for the active incremental data sources.
+ ASSERT_EQ(clears_seen.size(), kNumClears);
+ for (const std::vector<DataSourceInstanceID>& ds_ids : clears_seen) {
+ ASSERT_THAT(ds_ids, ElementsAreArray({ds_incremental1, ds_incremental2}));
+ }
+}
+
// Creates a tracing session where some of the data sources set the
// |will_notify_on_stop| flag and checks that the OnTracingDisabled notification
// to the consumer is delayed until the acks are received.
@@ -2327,6 +2434,62 @@ TEST_F(TracingServiceImplTest, ScrapeBuffersOnFlush) {
consumer->WaitForTracingDisabled();
}
+TEST_F(TracingServiceImplTest, ScrapeBuffersFromAnotherThread) {
+ // This test verifies that there are no reported TSAN races while scraping
+ // buffers from a producer which is actively writing more trace data
+ // concurrently.
+ svc->SetSMBScrapingEnabled(true);
+
+ std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
+ consumer->Connect(svc.get());
+
+ std::unique_ptr<MockProducer> producer = CreateMockProducer();
+ producer->Connect(svc.get(), "mock_producer");
+ ProducerID producer_id = *last_producer_id();
+ producer->RegisterDataSource("data_source");
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(128);
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("data_source");
+ ds_config->set_target_buffer(0);
+ consumer->EnableTracing(trace_config);
+
+ producer->WaitForTracingSetup();
+ producer->WaitForDataSourceSetup("data_source");
+ producer->WaitForDataSourceStart("data_source");
+ consumer->StartTracing();
+
+ std::unique_ptr<TraceWriter> writer = producer->endpoint()->CreateTraceWriter(
+ tracing_session()->buffers_index[0]);
+ WaitForTraceWritersChanged(producer_id);
+
+ constexpr int kPacketCount = 10;
+ std::atomic<int> packets_written{};
+ std::thread writer_thread([&] {
+ for (int i = 0; i < kPacketCount; i++) {
+ writer->NewTracePacket()->set_for_testing()->set_str("payload");
+ packets_written.store(i, std::memory_order_relaxed);
+ }
+ });
+
+ // Wait until the thread has had some time to write some packets.
+ while (packets_written.load(std::memory_order_relaxed) < kPacketCount / 2)
+ base::SleepMicroseconds(5000);
+
+ // Disabling tracing will trigger scraping.
+ consumer->DisableTracing();
+ writer_thread.join();
+
+ // Because we don't synchronize with the producer thread, we can't make any
+ // guarantees about the number of packets we will successfully read. We just
+ // verify that no TSAN races are reported.
+ consumer->ReadBuffers();
+
+ producer->WaitForDataSourceStop("data_source");
+ consumer->WaitForTracingDisabled();
+}
+
// Test scraping on producer disconnect.
TEST_F(TracingServiceImplTest, ScrapeBuffersOnProducerDisconnect) {
svc->SetSMBScrapingEnabled(true);
diff --git a/src/tracing/ipc/producer/producer_ipc_client_impl.cc b/src/tracing/ipc/producer/producer_ipc_client_impl.cc
index bb929f159..54bcb8066 100644
--- a/src/tracing/ipc/producer/producer_ipc_client_impl.cc
+++ b/src/tracing/ipc/producer/producer_ipc_client_impl.cc
@@ -164,11 +164,25 @@ void ProducerIPCClientImpl::OnServiceRequest(
// uint64 and not stdint's uint64_t. On some 64 bit archs they differ on the
// type (long vs long long) even though they have the same size.
const auto* data_source_ids = cmd.flush().data_source_ids().data();
- static_assert(sizeof(data_source_ids[0]) == sizeof(FlushRequestID),
+ static_assert(sizeof(data_source_ids[0]) == sizeof(DataSourceInstanceID),
"data_source_ids should be 64-bit");
- producer_->Flush(cmd.flush().request_id(),
- reinterpret_cast<const FlushRequestID*>(data_source_ids),
- static_cast<size_t>(cmd.flush().data_source_ids().size()));
+ producer_->Flush(
+ cmd.flush().request_id(),
+ reinterpret_cast<const DataSourceInstanceID*>(data_source_ids),
+ static_cast<size_t>(cmd.flush().data_source_ids().size()));
+ return;
+ }
+
+ if (cmd.cmd_case() ==
+ protos::GetAsyncCommandResponse::kClearIncrementalState) {
+ const auto* data_source_ids =
+ cmd.clear_incremental_state().data_source_ids().data();
+ static_assert(sizeof(data_source_ids[0]) == sizeof(DataSourceInstanceID),
+ "data_source_ids should be 64-bit");
+ producer_->ClearIncrementalState(
+ reinterpret_cast<const DataSourceInstanceID*>(data_source_ids),
+ static_cast<size_t>(
+ cmd.clear_incremental_state().data_source_ids().size()));
return;
}
diff --git a/src/tracing/ipc/service/producer_ipc_service.cc b/src/tracing/ipc/service/producer_ipc_service.cc
index 1eba3a801..90510589f 100644
--- a/src/tracing/ipc/service/producer_ipc_service.cc
+++ b/src/tracing/ipc/service/producer_ipc_service.cc
@@ -397,4 +397,21 @@ void ProducerIPCService::RemoteProducer::Flush(
async_producer_commands.Resolve(std::move(cmd));
}
+void ProducerIPCService::RemoteProducer::ClearIncrementalState(
+ const DataSourceInstanceID* data_source_ids,
+ size_t num_data_sources) {
+ if (!async_producer_commands.IsBound()) {
+ PERFETTO_DLOG(
+ "The Service tried to request an incremental state invalidation, but "
+ "the remote Producer has not yet initialized the connection");
+ return;
+ }
+ auto cmd = ipc::AsyncResult<protos::GetAsyncCommandResponse>::Create();
+ cmd.set_has_more(true);
+ for (size_t i = 0; i < num_data_sources; i++)
+ cmd->mutable_clear_incremental_state()->add_data_source_ids(
+ data_source_ids[i]);
+ async_producer_commands.Resolve(std::move(cmd));
+}
+
} // namespace perfetto
diff --git a/src/tracing/ipc/service/producer_ipc_service.h b/src/tracing/ipc/service/producer_ipc_service.h
index e6ebf0a08..5954680a9 100644
--- a/src/tracing/ipc/service/producer_ipc_service.h
+++ b/src/tracing/ipc/service/producer_ipc_service.h
@@ -92,6 +92,9 @@ class ProducerIPCService : public protos::ProducerPort {
const DataSourceInstanceID* data_source_ids,
size_t num_data_sources) override;
+ void ClearIncrementalState(const DataSourceInstanceID* data_source_ids,
+ size_t num_data_sources) override;
+
// The interface obtained from the core service business logic through
// Service::ConnectProducer(this). This allows to invoke methods for a
// specific Producer on the Service business logic.
diff --git a/src/tracing/test/mock_producer.cc b/src/tracing/test/mock_producer.cc
index 003a053a3..02c33ba88 100644
--- a/src/tracing/test/mock_producer.cc
+++ b/src/tracing/test/mock_producer.cc
@@ -59,11 +59,13 @@ void MockProducer::Connect(TracingService* svc,
void MockProducer::RegisterDataSource(const std::string& name,
bool ack_stop,
- bool ack_start) {
+ bool ack_start,
+ bool handle_incremental_state_clear) {
DataSourceDescriptor ds_desc;
ds_desc.set_name(name);
ds_desc.set_will_notify_on_stop(ack_stop);
ds_desc.set_will_notify_on_start(ack_start);
+ ds_desc.set_handles_incremental_state_clear(handle_incremental_state_clear);
service_endpoint_->RegisterDataSource(ds_desc);
}
diff --git a/src/tracing/test/mock_producer.h b/src/tracing/test/mock_producer.h
index 9d785512b..309467865 100644
--- a/src/tracing/test/mock_producer.h
+++ b/src/tracing/test/mock_producer.h
@@ -49,7 +49,8 @@ class MockProducer : public Producer {
size_t shared_memory_size_hint_bytes = 0);
void RegisterDataSource(const std::string& name,
bool ack_stop = false,
- bool ack_start = false);
+ bool ack_start = false,
+ bool handle_incremental_state_clear = false);
void UnregisterDataSource(const std::string& name);
void RegisterTraceWriter(uint32_t writer_id, uint32_t target_buffer);
void UnregisterTraceWriter(uint32_t writer_id);
@@ -84,6 +85,8 @@ class MockProducer : public Producer {
MOCK_METHOD0(OnTracingSetup, void());
MOCK_METHOD3(Flush,
void(FlushRequestID, const DataSourceInstanceID*, size_t));
+ MOCK_METHOD2(ClearIncrementalState,
+ void(const DataSourceInstanceID*, size_t));
private:
base::TestTaskRunner* const task_runner_;
diff --git a/src/tracing/test/tracing_integration_test.cc b/src/tracing/test/tracing_integration_test.cc
index 161713cfb..41fd1d4f9 100644
--- a/src/tracing/test/tracing_integration_test.cc
+++ b/src/tracing/test/tracing_integration_test.cc
@@ -50,6 +50,7 @@ using testing::_;
constexpr char kProducerSockName[] = TEST_SOCK_NAME("tracing_test-producer");
constexpr char kConsumerSockName[] = TEST_SOCK_NAME("tracing_test-consumer");
+// TODO(rsavitski): consider using src/tracing/test/mock_producer.h.
class MockProducer : public Producer {
public:
~MockProducer() override {}
@@ -66,6 +67,8 @@ class MockProducer : public Producer {
MOCK_METHOD0(OnTracingSetup, void());
MOCK_METHOD3(Flush,
void(FlushRequestID, const DataSourceInstanceID*, size_t));
+ MOCK_METHOD2(ClearIncrementalState,
+ void(const DataSourceInstanceID*, size_t));
};
class MockConsumer : public Consumer {
diff --git a/test/end_to_end_integrationtest.cc b/test/end_to_end_integrationtest.cc
index 267635427..b9d14e976 100644
--- a/test/end_to_end_integrationtest.cc
+++ b/test/end_to_end_integrationtest.cc
@@ -658,10 +658,10 @@ TEST_F(PerfettoCmdlineTest, NoSanitizers(StartTracingTrigger)) {
// time.
trigger->set_stop_delay_ms(500);
- // We have 5 normal preample packets (trace config, clock, system info, sync
- // marker, stats) and then since this is a trace with a trigger config we have
- // an additional ReceivedTriggers packet.
- constexpr size_t kPreamblePackets = 6;
+ // We have 6 normal preamble packets (start clock, trace config, clock,
+ // system info, sync marker, stats) and then since this is a trace with a
+ // trigger config we have an additional ReceivedTriggers packet.
+ constexpr size_t kPreamblePackets = 7;
base::TestTaskRunner task_runner;
@@ -735,10 +735,10 @@ TEST_F(PerfettoCmdlineTest, NoSanitizers(StopTracingTrigger)) {
trigger->set_name("trigger_name_3");
trigger->set_stop_delay_ms(60000);
- // We have 5 normal preample packets (trace config, clock, system info, sync
- // marker, stats) and then since this is a trace with a trigger config we have
- // an additional ReceivedTriggers packet.
- constexpr size_t kPreamblePackets = 7;
+ // We have 6 normal preamble packets (start clock, trace config, clock,
+ // system info, sync marker, stats) and then since this is a trace with a
+ // trigger config we have an additional ReceivedTriggers packet.
+ constexpr size_t kPreamblePackets = 8;
base::TestTaskRunner task_runner;
diff --git a/test/end_to_end_shared_memory_fuzzer.cc b/test/end_to_end_shared_memory_fuzzer.cc
index 3c324097e..c390340e0 100644
--- a/test/end_to_end_shared_memory_fuzzer.cc
+++ b/test/end_to_end_shared_memory_fuzzer.cc
@@ -99,6 +99,7 @@ class FakeProducer : public Producer {
void StopDataSource(DataSourceInstanceID) override {}
void OnTracingSetup() override {}
void Flush(FlushRequestID, const DataSourceInstanceID*, size_t) override {}
+ void ClearIncrementalState(const DataSourceInstanceID*, size_t) {}
private:
const std::string name_;
diff --git a/test/fake_producer.h b/test/fake_producer.h
index 5e8d58759..460d88c11 100644
--- a/test/fake_producer.h
+++ b/test/fake_producer.h
@@ -54,6 +54,8 @@ class FakeProducer : public Producer {
void StopDataSource(DataSourceInstanceID) override;
void OnTracingSetup() override;
void Flush(FlushRequestID, const DataSourceInstanceID*, size_t) override;
+ void ClearIncrementalState(const DataSourceInstanceID* /*data_source_ids*/,
+ size_t /*num_data_sources*/) override {}
private:
void Shutdown();
diff --git a/tools/gen_build b/tools/gen_build
index d03f8d2f8..2bfbb3d0b 100755
--- a/tools/gen_build
+++ b/tools/gen_build
@@ -54,7 +54,8 @@ header = """# Copyright (C) 2019 The Android Open Source Project
""".format(__file__)
# Arguments for the GN output directory.
-gn_args = 'target_os="linux" is_debug=false'
+# host_os="linux" is to generate the right build files from Mac OS.
+gn_args = 'target_os="linux" is_debug=false host_os="linux"'
# Default targets to translate to the blueprint file.
default_targets = [
diff --git a/tools/gen_tracing_cpp_headers_from_protos b/tools/gen_tracing_cpp_headers_from_protos
index 7728949d9..9ae472a8d 100755
--- a/tools/gen_tracing_cpp_headers_from_protos
+++ b/tools/gen_tracing_cpp_headers_from_protos
@@ -40,7 +40,7 @@ PROTOS = (
HEADER_PATH = 'include/perfetto/tracing/core'
CPP_PATH = 'src/tracing/core'
INCLUDE_PATH = 'perfetto/tracing/core'
-
+ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
def run(cmd):
print('\nRunning ' + ' '.join(cmd))
@@ -55,7 +55,9 @@ def main():
print('Usage: %s out/xxx' % sys.argv[0])
return 1
out_dir = sys.argv[1]
- clang_format = ['clang-format', '-i', '--sort-includes']
+ arch = 'mac' if sys.platform == 'darwin' else 'linux64'
+ clang_format_path = os.path.join(ROOT_DIR, 'buildtools', arch, 'clang-format')
+ clang_format = [clang_format_path, '-i', '--sort-includes']
tool = os.path.join(out_dir, 'proto_to_cpp')
if not os.path.exists(tool):
print('Could not find %s, run ninja -C %s proto_to_cpp' % (tool, out_dir))