Merge "Fix multithreaded_alloc build."
diff --git a/Android.bp b/Android.bp
index f13c5c6..68c4084 100644
--- a/Android.bp
+++ b/Android.bp
@@ -2173,12 +2173,42 @@
genrule {
name: "perfetto_protos_perfetto_config_descriptor",
srcs: [
+ "protos/perfetto/common/android_log_constants.proto",
+ "protos/perfetto/common/builtin_clock.proto",
+ "protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/data_source_descriptor.proto",
+ "protos/perfetto/common/descriptor.proto",
+ "protos/perfetto/common/gpu_counter_descriptor.proto",
+ "protos/perfetto/common/observable_events.proto",
+ "protos/perfetto/common/sys_stats_counters.proto",
+ "protos/perfetto/common/trace_stats.proto",
+ "protos/perfetto/common/tracing_service_capabilities.proto",
+ "protos/perfetto/common/tracing_service_state.proto",
+ "protos/perfetto/common/track_event_descriptor.proto",
+ "protos/perfetto/config/android/android_log_config.proto",
+ "protos/perfetto/config/android/android_polled_state_config.proto",
+ "protos/perfetto/config/android/packages_list_config.proto",
+ "protos/perfetto/config/chrome/chrome_config.proto",
+ "protos/perfetto/config/data_source_config.proto",
+ "protos/perfetto/config/ftrace/ftrace_config.proto",
+ "protos/perfetto/config/gpu/gpu_counter_config.proto",
+ "protos/perfetto/config/gpu/vulkan_memory_config.proto",
+ "protos/perfetto/config/inode_file/inode_file_config.proto",
+ "protos/perfetto/config/power/android_power_config.proto",
+ "protos/perfetto/config/process_stats/process_stats_config.proto",
+ "protos/perfetto/config/profiling/heapprofd_config.proto",
+ "protos/perfetto/config/profiling/java_hprof_config.proto",
+ "protos/perfetto/config/profiling/perf_event_config.proto",
+ "protos/perfetto/config/stress_test_config.proto",
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ "protos/perfetto/config/test_config.proto",
"protos/perfetto/config/trace_config.proto",
+ "protos/perfetto/config/track_event/track_event_config.proto",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) --include_imports $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
out: [
"perfetto_protos_perfetto_config_descriptor.bin",
],
@@ -3290,12 +3320,37 @@
genrule {
name: "perfetto_protos_perfetto_metrics_chrome_descriptor",
srcs: [
+ "protos/perfetto/metrics/android/batt_metric.proto",
+ "protos/perfetto/metrics/android/cpu_metric.proto",
+ "protos/perfetto/metrics/android/display_metrics.proto",
+ "protos/perfetto/metrics/android/gpu_metric.proto",
+ "protos/perfetto/metrics/android/heap_profile_callsites.proto",
+ "protos/perfetto/metrics/android/hwui_metric.proto",
+ "protos/perfetto/metrics/android/ion_metric.proto",
+ "protos/perfetto/metrics/android/java_heap_histogram.proto",
+ "protos/perfetto/metrics/android/java_heap_stats.proto",
+ "protos/perfetto/metrics/android/lmk_metric.proto",
+ "protos/perfetto/metrics/android/lmk_reason_metric.proto",
+ "protos/perfetto/metrics/android/mem_metric.proto",
+ "protos/perfetto/metrics/android/mem_unagg_metric.proto",
+ "protos/perfetto/metrics/android/package_list.proto",
+ "protos/perfetto/metrics/android/powrails_metric.proto",
+ "protos/perfetto/metrics/android/process_metadata.proto",
+ "protos/perfetto/metrics/android/startup_metric.proto",
+ "protos/perfetto/metrics/android/surfaceflinger.proto",
+ "protos/perfetto/metrics/android/sysui_cuj_metrics.proto",
+ "protos/perfetto/metrics/android/task_names.proto",
+ "protos/perfetto/metrics/android/thread_time_in_state_metric.proto",
+ "protos/perfetto/metrics/android/unsymbolized_frames.proto",
"protos/perfetto/metrics/chrome/all_chrome_metrics.proto",
+ "protos/perfetto/metrics/chrome/test_chrome_metric.proto",
+ "protos/perfetto/metrics/custom_options.proto",
+ "protos/perfetto/metrics/metrics.proto",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --proto_path=external/protobuf/src --descriptor_set_out=$(out) --include_imports $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --proto_path=external/protobuf/src --descriptor_set_out=$(out) $(in)",
out: [
"perfetto_protos_perfetto_metrics_chrome_descriptor.bin",
],
@@ -3305,12 +3360,34 @@
genrule {
name: "perfetto_protos_perfetto_metrics_descriptor",
srcs: [
+ "protos/perfetto/metrics/android/batt_metric.proto",
+ "protos/perfetto/metrics/android/cpu_metric.proto",
+ "protos/perfetto/metrics/android/display_metrics.proto",
+ "protos/perfetto/metrics/android/gpu_metric.proto",
+ "protos/perfetto/metrics/android/heap_profile_callsites.proto",
+ "protos/perfetto/metrics/android/hwui_metric.proto",
+ "protos/perfetto/metrics/android/ion_metric.proto",
+ "protos/perfetto/metrics/android/java_heap_histogram.proto",
+ "protos/perfetto/metrics/android/java_heap_stats.proto",
+ "protos/perfetto/metrics/android/lmk_metric.proto",
+ "protos/perfetto/metrics/android/lmk_reason_metric.proto",
+ "protos/perfetto/metrics/android/mem_metric.proto",
+ "protos/perfetto/metrics/android/mem_unagg_metric.proto",
+ "protos/perfetto/metrics/android/package_list.proto",
+ "protos/perfetto/metrics/android/powrails_metric.proto",
+ "protos/perfetto/metrics/android/process_metadata.proto",
+ "protos/perfetto/metrics/android/startup_metric.proto",
+ "protos/perfetto/metrics/android/surfaceflinger.proto",
+ "protos/perfetto/metrics/android/sysui_cuj_metrics.proto",
+ "protos/perfetto/metrics/android/task_names.proto",
+ "protos/perfetto/metrics/android/thread_time_in_state_metric.proto",
+ "protos/perfetto/metrics/android/unsymbolized_frames.proto",
"protos/perfetto/metrics/metrics.proto",
],
tools: [
"aprotoc",
],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) --include_imports $(in)",
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
out: [
"perfetto_protos_perfetto_metrics_descriptor.bin",
],
diff --git a/buildtools/.gitignore b/buildtools/.gitignore
index 6da14ac..d7423b6 100644
--- a/buildtools/.gitignore
+++ b/buildtools/.gitignore
@@ -1,4 +1,8 @@
android-core/
+android-libbase/
+android-libprocinfo/
+android-logging/
+android-unwinding/
android_sdk/
aosp-*/
benchmark/
diff --git a/docs/contributing/chrome-branches.md b/docs/contributing/chrome-branches.md
index ae58d04..3530f5f 100644
--- a/docs/contributing/chrome-branches.md
+++ b/docs/contributing/chrome-branches.md
@@ -5,8 +5,6 @@
the branch, and updating the `DEPS` file in Chrome's milestone branch to point
to the new perfetto branch's head.
-[TOC]
-
## Creating the perfetto branch {#branch}
1. Determine the branch name: **`chromium/XXXX`**, where `XXXX` is the branch
diff --git a/gn/proto_library.gni b/gn/proto_library.gni
index 1fa5d58..a52982b 100644
--- a/gn/proto_library.gni
+++ b/gn/proto_library.gni
@@ -85,7 +85,16 @@
deps = []
}
- deps += [ perfetto_root_path + "src/protozero" ]
+ # omit_protozero_dep is intended to be used when protozero_library
+ # is used in Chrome (for generation of code for proto extensions)
+ # to avoid ODR violations in case of component builds. The embedder
+ # (Chrome) is then responsible for adding the appropriate transitive
+ # dependency on Protozero.
+ #
+ # TODO(b/173041866): use fine-grained components instead when available
+ if (!(defined(invoker.omit_protozero_dep) && invoker.omit_protozero_dep)) {
+ deps += [ perfetto_root_path + "src/protozero" ]
+ }
forward_variables_from(invoker,
[
diff --git a/src/profiling/symbolizer/local_symbolizer_unittest.cc b/src/profiling/symbolizer/local_symbolizer_unittest.cc
index 72841f0..b96d318 100644
--- a/src/profiling/symbolizer/local_symbolizer_unittest.cc
+++ b/src/profiling/symbolizer/local_symbolizer_unittest.cc
@@ -34,9 +34,9 @@
stream.get(buffer, static_cast<int>(size), '\0');
return strlen(buffer);
};
- std::vector<std::string> lines = perfetto::profiling::GetLines(read_callback);
+ std::vector<std::string> lines = GetLines(read_callback);
std::istringstream validation(raw_contents);
- for (std::string actual : lines) {
+ for (const std::string& actual : lines) {
std::string expected;
getline(validation, expected);
EXPECT_EQ(actual, expected);
@@ -72,6 +72,29 @@
RunAndValidateParseLines(raw_contents);
}
+TEST(LocalSymbolizerTest, ParseLinesSingleCharRead) {
+ std::string raw_contents =
+ "FSlateRHIRenderingPolicy::DrawElements(FRHICommandListImmediate&, "
+ "FSlateBackBuffer&, TRefCountPtr<FRHITexture2D>&, "
+ "TRefCountPtr<FRHITexture2D>&, TRefCountPtr<FRHITexture2D>&, int, "
+ "TArray<FSlateRenderBatch, TSizedDefaultAllocator<32> > const&, "
+ "FSlateRenderingParams const&)\n"
+ "F:/P4/EngineReleaseA/Engine/Source/Runtime/SlateRHIRenderer/"
+ "Private\\SlateRHIRenderingPolicy.cpp:1187:19\n";
+ std::istringstream stream(raw_contents);
+ auto read_callback = [&stream](char* buffer, size_t) {
+ stream.get(buffer, 1, '\0');
+ return strlen(buffer);
+ };
+ std::vector<std::string> lines = GetLines(read_callback);
+ std::istringstream validation(raw_contents);
+ for (const std::string& actual : lines) {
+ std::string expected;
+ getline(validation, expected);
+ EXPECT_EQ(actual, expected);
+ }
+}
+
} // namespace
} // namespace profiling
} // namespace perfetto
diff --git a/src/profiling/symbolizer/scoped_read_mmap_windows.cc b/src/profiling/symbolizer/scoped_read_mmap_windows.cc
index 6fc9fdd..7c55e66 100644
--- a/src/profiling/symbolizer/scoped_read_mmap_windows.cc
+++ b/src/profiling/symbolizer/scoped_read_mmap_windows.cc
@@ -36,7 +36,7 @@
PERFETTO_DLOG("Failed to mmap file");
return;
}
- ptr_ = MapViewOfFile(map_, FILE_MAP_READ, 0, 0, length);
+ ptr_ = MapViewOfFile(map_, FILE_MAP_READ, 0, 0, length_);
if (ptr_ == nullptr) {
PERFETTO_DLOG("Failed to map view of file");
}
diff --git a/src/profiling/symbolizer/subprocess_posix.cc b/src/profiling/symbolizer/subprocess_posix.cc
index de7527a..7d262a8 100644
--- a/src/profiling/symbolizer/subprocess_posix.cc
+++ b/src/profiling/symbolizer/subprocess_posix.cc
@@ -16,6 +16,8 @@
#include "src/profiling/symbolizer/subprocess.h"
+#include <signal.h>
+#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
diff --git a/src/trace_processor/metrics/android/android_sysui_cuj.sql b/src/trace_processor/metrics/android/android_sysui_cuj.sql
index 531ebbc..0588e52 100644
--- a/src/trace_processor/metrics/android/android_sysui_cuj.sql
+++ b/src/trace_processor/metrics/android/android_sysui_cuj.sql
@@ -51,6 +51,12 @@
JOIN last_cuj USING (upid)
WHERE thread.name = 'GPU completion'
),
+hwc_release_thread AS (
+ SELECT thread.*, last_cuj.ts_start as ts_cuj_start, last_cuj.ts_end as ts_cuj_end
+ FROM thread
+ JOIN last_cuj USING (upid)
+ WHERE thread.name = 'HWC release'
+),
main_thread_slices AS (
SELECT slice.*, ts + dur AS ts_end
FROM slice
@@ -65,7 +71,11 @@
WHERE ts >= ts_cuj_start AND ts <= ts_cuj_end
),
gpu_completion_slices AS (
- SELECT slice.*, ts + dur AS ts_end
+ SELECT
+ slice.*,
+ ts + dur AS ts_end,
+ -- Extracts 1234 from 'waiting for GPU completion 1234'
+ CAST(STR_SPLIT(slice.name, ' ', 4) AS INTEGER) as idx
FROM slice
JOIN thread_track ON slice.track_id = thread_track.id
JOIN gpu_completion_thread USING (utid)
@@ -73,6 +83,19 @@
slice.name LIKE 'waiting for GPU completion %'
AND ts >= ts_cuj_start AND ts <= ts_cuj_end
),
+hwc_release_slices AS (
+ SELECT
+ slice.*,
+ ts + dur as ts_end,
+ -- Extracts 1234 from 'waiting for HWC release 1234'
+ CAST(STR_SPLIT(slice.name, ' ', 4) AS INTEGER) as idx
+ FROM slice
+ JOIN thread_track ON slice.track_id = thread_track.id
+ JOIN hwc_release_thread USING (utid)
+ WHERE
+ slice.name LIKE 'waiting for HWC release %'
+ AND ts >= ts_cuj_start AND ts <= ts_cuj_end
+),
frames AS (
SELECT
ROW_NUMBER() OVER (ORDER BY mts.ts) AS frame_number,
@@ -96,32 +119,32 @@
SELECT
f.frame_number,
mts.state,
- SUM(mts.dur) / 1000000 AS duration_millis,
+ SUM(mts.dur) AS dur,
SUM(mts.io_wait) AS io_wait
FROM frames f
JOIN thread_state mts
ON mts.ts >= f.ts_main_thread_start AND mts.ts < f.ts_main_thread_end
WHERE mts.utid = (SELECT main_thread_utid FROM last_cuj)
GROUP BY f.frame_number, mts.state
- HAVING duration_millis > 0
+ HAVING mts.dur > 0
),
render_thread_state AS (
SELECT
f.frame_number,
rts.state,
- SUM(rts.dur) / 1000000 AS duration_millis,
+ SUM(rts.dur) AS dur,
SUM(rts.io_wait) AS io_wait
FROM frames f
JOIN thread_state rts
ON rts.ts >= f.ts_render_thread_start AND rts.ts < f.ts_render_thread_end
WHERE rts.utid in (SELECT utid FROM render_thread)
GROUP BY f.frame_number, rts.state
- HAVING duration_millis > 0
+ HAVING rts.dur > 0
),
main_thread_binder AS (
SELECT
f.frame_number,
- SUM(mts.dur) / 1000000 AS duration_millis,
+ SUM(mts.dur) AS dur,
COUNT(*) AS call_count
FROM frames f
JOIN main_thread_slices mts
@@ -137,7 +160,7 @@
JOIN render_thread_slices rts
ON rts.ts >= f.ts_render_thread_start AND rts.ts < f.ts_render_thread_end
WHERE rts.name = 'shader_compile'
- AND rts.dur / 1000000 > 8
+ AND rts.dur > 8000000
UNION ALL
SELECT
@@ -147,28 +170,46 @@
JOIN render_thread_slices rts
ON rts.ts >= f.ts_render_thread_start AND rts.ts < f.ts_render_thread_end
WHERE rts.name = 'flush layers'
- AND rts.dur / 1000000 > 8
+ AND rts.dur > 8000000
UNION ALL
SELECT
frame_number,
'MainThread - IO wait time' AS jank_cause
FROM main_thread_state
- WHERE state = 'DK' AND duration_millis > 8
+ WHERE state = 'DK' AND dur > 8000000
+
+ UNION ALL
+ SELECT
+ frame_number,
+ 'MainThread - scheduler' AS jank_cause
+ FROM main_thread_state
+ WHERE
+ (state = 'R' OR state = 'R+')
+ AND dur > 8000000
UNION ALL
SELECT
frame_number,
'RenderThread - IO wait time' AS jank_cause
FROM render_thread_state
- WHERE state = 'DK' AND duration_millis > 8
+ WHERE state = 'DK' AND dur > 8000000
+
+ UNION ALL
+ SELECT
+ frame_number,
+ 'RenderThread - scheduler' AS jank_cause
+ FROM render_thread_state
+ WHERE
+ (state = 'R' OR state = 'R+')
+ AND dur > 8000000
UNION ALL
SELECT
frame_number,
'MainThread - binder transaction time' AS jank_cause
FROM main_thread_binder
- WHERE duration_millis > 8
+ WHERE dur > 8000000
UNION ALL
SELECT
@@ -176,6 +217,26 @@
'MainThread - binder calls count' AS jank_cause
FROM main_thread_binder
WHERE call_count > 8
+
+ UNION ALL
+ SELECT
+ frame_number,
+ 'GPU completion - long completion time' AS jank_cause
+ FROM frames f
+ JOIN gpu_completion_slices gpu ON gpu.ts_end = f.ts_frame_end
+ LEFT JOIN hwc_release_slices hwc USING (idx)
+ WHERE (gpu.ts_end - MAX(COALESCE(hwc.ts_end, 0), gpu.ts)) > 8000000
+
+ UNION ALL
+ SELECT
+ frame_number,
+ 'Long running time' as jank_cause
+ FROM main_thread_state mts
+ JOIN render_thread_state rts USING(frame_number)
+ WHERE
+ mts.state = 'Running'
+ AND rts.state = 'Running'
+ AND mts.dur + rts.dur > 15000000
)
SELECT
AndroidSysUiCujMetrics(
diff --git a/test/trace_processor/graphics/android_sysui_cuj.out b/test/trace_processor/graphics/android_sysui_cuj.out
index c1b7163..e37dd4a 100644
--- a/test/trace_processor/graphics/android_sysui_cuj.out
+++ b/test/trace_processor/graphics/android_sysui_cuj.out
@@ -17,4 +17,17 @@
jank_cause: "MainThread - binder calls count"
jank_cause: "RenderThread - long flush layers"
}
+ frames {
+ number: 4
+ ts: 40000000
+ dur: 38000000
+ jank_cause: "GPU completion - long completion time"
+ jank_cause: "Long running time"
+ }
+ frames {
+ number: 5
+ ts: 70000000
+ dur: 18000000
+ jank_cause: "RenderThread - scheduler"
+ }
}
\ No newline at end of file
diff --git a/test/trace_processor/graphics/android_sysui_cuj.py b/test/trace_processor/graphics/android_sysui_cuj.py
index a7e6180..a336ff0 100644
--- a/test/trace_processor/graphics/android_sysui_cuj.py
+++ b/test/trace_processor/graphics/android_sysui_cuj.py
@@ -18,6 +18,7 @@
import synth_common
PID = 1000
+RTID = 1555
def add_main_thread_atrace(trace, ts, ts_end, buf):
@@ -26,8 +27,8 @@
def add_render_thread_atrace(trace, ts, ts_end, buf):
- trace.add_atrace_begin(ts=ts, tid=1555, pid=PID, buf=buf)
- trace.add_atrace_end(ts=ts_end, tid=1555, pid=PID)
+ trace.add_atrace_begin(ts=ts, tid=RTID, pid=PID, buf=buf)
+ trace.add_atrace_end(ts=ts_end, tid=RTID, pid=PID)
def add_gpu_thread_atrace(trace, ts, ts_end, buf):
@@ -52,7 +53,7 @@
trace.add_process(pid=PID, ppid=1, cmdline="com.android.systemui", uid=10001)
trace.add_thread(
- tid=1555, tgid=PID, cmdline="RenderThread", name="RenderThread")
+ tid=RTID, tgid=PID, cmdline="RenderThread", name="RenderThread")
trace.add_thread(
tid=1666, tgid=PID, cmdline="GPU completion", name="GPU completion")
@@ -115,4 +116,41 @@
add_render_thread_atrace(
trace, ts=40_000_000, ts_end=52_000_000, buf="flush layers")
+add_frame(
+ trace,
+ ts_do_frame=40_000_000,
+ ts_end_do_frame=53_000_000,
+ ts_draw_frame=60_000_000,
+ ts_end_draw_frame=66_000_000,
+ ts_gpu=66_500_000,
+ ts_end_gpu=78_000_000)
+
+# Main thread Running for 13 millis
+trace.add_sched(ts=40_000_000, prev_pid=0, next_pid=PID)
+trace.add_sched(ts=53_000_000, prev_pid=PID, next_pid=0, prev_state='R')
+
+# RenderThread Running for 5 millis
+trace.add_sched(ts=61_000_000, prev_pid=0, next_pid=RTID)
+trace.add_sched(ts=66_000_000, prev_pid=RTID, next_pid=0, prev_state='R')
+
+add_frame(
+ trace,
+ ts_do_frame=70_000_000,
+ ts_end_do_frame=80_000_000,
+ ts_draw_frame=78_000_000,
+ ts_end_draw_frame=87_000_000,
+ ts_gpu=86_500_000,
+ ts_end_gpu=88_000_000)
+
+# Main thread Running for 1 millis
+trace.add_sched(ts=70_000_000, prev_pid=0, next_pid=PID)
+trace.add_sched(ts=71_000_000, prev_pid=PID, next_pid=0, prev_state='R')
+
+# RenderThread Running for 1 millis and R for 9.5 millis
+trace.add_sched(ts=78_000_000, prev_pid=0, next_pid=RTID)
+trace.add_sched(ts=78_500_000, prev_pid=RTID, next_pid=0, prev_state='R')
+trace.add_sched(ts=78_500_000, prev_pid=0, next_pid=0)
+trace.add_sched(ts=88_000_000, prev_pid=0, next_pid=RTID)
+trace.add_sched(ts=88_500_000, prev_pid=RTID, next_pid=0, prev_state='R')
+
sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index 3f2ea43..ec9c1b7 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -26,6 +26,7 @@
# libraries are also mapped to their Android equivalents -- see |builtin_deps|.
import argparse
+import collections
import json
import os
import re
@@ -615,7 +616,7 @@
if target.proto_plugin == 'descriptor':
out = '{}.bin'.format(target_module_name)
- cmd += ['--descriptor_set_out=$(out)', '--include_imports']
+ cmd += ['--descriptor_set_out=$(out)']
cmd += ['$(in)']
descriptor_module = Module('genrule', target_module_name, target.name)
@@ -624,6 +625,21 @@
descriptor_module.tools = tools
blueprint.add_module(descriptor_module)
+ # Recursively extract the .proto files of all the dependencies and
+ # add them to srcs.
+ target_queue = collections.deque([target.name])
+ seen_targets = set()
+ while target_queue:
+ dep = target_queue.popleft()
+ if dep in seen_targets:
+ continue
+ seen_targets.add(dep)
+
+ current_target = gn.get_target(dep)
+ descriptor_module.srcs.update(
+ gn_utils.label_to_path(src) for src in current_target.sources)
+ target_queue.extend(current_target.proto_deps)
+
return descriptor_module
# We create two genrules for each proto target: one for the headers and
diff --git a/ui/src/controller/adb_socket_controller.ts b/ui/src/controller/adb_socket_controller.ts
index 7dd7b1d..f517f7a 100644
--- a/ui/src/controller/adb_socket_controller.ts
+++ b/ui/src/controller/adb_socket_controller.ts
@@ -161,7 +161,11 @@
}
private parseMessage(frameBuffer: Uint8Array) {
- const frame = perfetto.protos.IPCFrame.decode(frameBuffer);
+ // Copy message to new array:
+ const buf = new ArrayBuffer(frameBuffer.byteLength);
+ const arr = new Uint8Array(buf);
+ arr.set(frameBuffer);
+ const frame = perfetto.protos.IPCFrame.decode(arr);
this.handleIncomingFrame(frame);
}