git: 7185635a576f - main - devel/perfetto: update to 57.2
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 09 Jul 2026 21:40:21 UTC
The branch main has been updated by siva:
URL: https://cgit.FreeBSD.org/ports/commit/?id=7185635a576f831efd3885b29a932b7efaf53836
commit 7185635a576f831efd3885b29a932b7efaf53836
Author: Siva Mahadevan <siva@FreeBSD.org>
AuthorDate: 2026-07-08 21:38:59 +0000
Commit: Siva Mahadevan <siva@FreeBSD.org>
CommitDate: 2026-07-09 21:39:30 +0000
devel/perfetto: update to 57.2
* All freebsd-specific patches have been vendored in from
https://codeberg.org/tj/perfetto/src/branch/v54.0-freebsd-ports
* Non-upstreamed FreeBSD-specific binaries have a "perfetto_" prefix
added to them to avoid conflict with other ports
---
devel/perfetto/Makefile | 42 +-
devel/perfetto/distinfo | 18 +-
devel/perfetto/files/patch-BUILD.gn | 12 +
.../perfetto/files/patch-examples_dtrace_BUILD.gn | 36 ++
.../files/patch-examples_dtrace_dtrace__probe.c | 416 +++++++++++++++++
...tch-examples_dtrace_examples_dtrace__probes.cfg | 21 +
.../perfetto/files/patch-examples_freebsd_BUILD.gn | 52 +++
.../patch-examples_freebsd_examples_power.cfg | 15 +
.../patch-examples_freebsd_freebsd__sys__stats.c | 99 ++++
...tch-examples_freebsd_freebsd__sys__stats__cpu.c | 309 +++++++++++++
...ch-examples_freebsd_freebsd__sys__stats__disk.c | 155 +++++++
...ch-examples_freebsd_freebsd__sys__stats__intr.c | 83 ++++
.../perfetto/files/patch-examples_freebsd_power.c | 497 +++++++++++++++++++++
.../files/patch-include_perfetto_public_BUILD.gn | 10 +
.../files/patch-protos_perfetto_config_BUILD.gn | 10 +
...otos_perfetto_config_data__source__config.proto | 29 ++
.../patch-protos_perfetto_config_dtrace_BUILD.gn | 25 ++
...tos_perfetto_config_dtrace_dtrace__config.proto | 34 ++
.../perfetto/files/patch-src_tracebox_tracebox.cc | 60 +++
devel/perfetto/pkg-plist | 34 +-
20 files changed, 1922 insertions(+), 35 deletions(-)
diff --git a/devel/perfetto/Makefile b/devel/perfetto/Makefile
index 88c25e8f9682..a787bc000ce9 100644
--- a/devel/perfetto/Makefile
+++ b/devel/perfetto/Makefile
@@ -1,12 +1,7 @@
PORTNAME= perfetto
DISTVERSIONPREFIX= v
-DISTVERSION= 54.0
+DISTVERSION= 57.2
CATEGORIES= devel
-
-MAINTAINER= siva@FreeBSD.org
-COMMENT= System profiling, app tracing, and trace analysis
-WWW= https://perfetto.dev/
-
MASTER_SITES= https://storage.googleapis.com/perfetto/:perfetto
DISTFILES= sqlite-amalgamation-3500300.zip:perfetto \
llvm-project-617a15a9eac96088ae5e9134248d8236e34b91b1.tgz:perfetto
@@ -14,25 +9,25 @@ DISTFILES= sqlite-amalgamation-3500300.zip:perfetto \
LICENSE= APACHE20
LICENSE_FILE= ${WRKSRC}/LICENSE
-PATCH_SITES= https://github.com/google/perfetto/commit/:upstream \
- https://codeberg.org/tj/perfetto/commit/:tj
-PATCHFILES= 0a47f21e97615e0259dcb8589190aa0912c47bbe.patch:upstream \
- d400ae17f63c91846fb489dc716109fbfac311a4.patch:tj \
- 0e50ef0b9372580b18c2693a1f4a95cb8ee8abc7.patch:tj \
- 6620157cb2a8cf3334219fce26cd91d8089a8cd2.patch:tj \
- 1b24730762d082dae073f096d5e666e0fc83a1bb.patch:tj
-
-PATCH_DIST_STRIP= -p1
+MAINTAINER= siva@FreeBSD.org
+COMMENT= System profiling, app tracing, and trace analysis
+WWW= https://perfetto.dev/
BUILD_DEPENDS= gn:devel/gn
USES= compiler:c++17-lang ninja python:build
+OPTIONS_DEFINE= EXAMPLES
+OPTIONS_DEFAULT= EXAMPLES
+OPTIONS_SUB= YES
+
USE_GITHUB= yes
GH_ACCOUNT= google
+# Taken from tools/install-build-deps
GH_TUPLE= protocolbuffers:protobuf:v31.1:buildtools_protobuf/buildtools/protobuf \
abseil:abseil-cpp:20250512.1:buildtools_abseil_cpp/buildtools/abseil-cpp \
sqlite:sqlite:version-3.50.3:buildtools_sqlite_src/buildtools/sqlite_src \
+ google:re2:927f5d53caf8111721e734cf24724686bb745f55:buildtools_re2/buildtools/re2 \
libexpat:libexpat:R_2_6_2:buildtools_expat/buildtools/expat/src
GN_ARGS= is_debug=false \
@@ -45,7 +40,9 @@ BINARY_ALIAS= python3=${PYTHON_CMD}
BUILD_WRKSRC= ${WRKSRC}/out
-ALL_TARGET= dtrace_probe freebsd_power freebsd_sys libperfetto_c.so perfetto tracebox traceconv traced traced_relay
+_PERFETTO_TARGETS= perfetto tracebox traceconv traced traced_relay
+_FREEBSD_TARGETS= dtrace_probe freebsd_power freebsd_sys
+ALL_TARGET= libperfetto.a libperfetto_c.so ${_PERFETTO_TARGETS} ${_FREEBSD_TARGETS}
post-extract:
${MV} ${WRKDIR}/sqlite-amalgamation-3500300 ${WRKSRC}/buildtools/sqlite
@@ -62,10 +59,17 @@ do-configure:
${BUILD_WRKSRC}
do-install:
- cd ${BUILD_WRKSRC} && ${INSTALL_PROGRAM} \
- dtrace_probe freebsd_power freebsd_sys perfetto tracebox traceconv traced traced_relay \
- ${STAGEDIR}${PREFIX}/bin
${INSTALL_PROGRAM} ${BUILD_WRKSRC}/libperfetto_c.so ${STAGEDIR}${PREFIX}/lib
${INSTALL_DATA} ${BUILD_WRKSRC}/libperfetto.a ${STAGEDIR}${PREFIX}/lib
+.for b in ${_PERFETTO_TARGETS}
+ ${INSTALL_PROGRAM} ${BUILD_WRKSRC}/${b} ${STAGEDIR}${PREFIX}/bin
+.endfor
+.for b in ${_FREEBSD_TARGETS}
+ ${INSTALL_PROGRAM} ${BUILD_WRKSRC}/${b} ${STAGEDIR}${PREFIX}/bin/perfetto_${b}
+.endfor
+
+post-install-EXAMPLES-on:
+ ${MKDIR} ${STAGEDIR}${EXAMPLESDIR}
+ cd ${WRKSRC}/examples && ${COPYTREE_SHARE} . ${STAGEDIR}${EXAMPLESDIR}
.include <bsd.port.mk>
diff --git a/devel/perfetto/distinfo b/devel/perfetto/distinfo
index 35fd277f71d6..23c7606e2da6 100644
--- a/devel/perfetto/distinfo
+++ b/devel/perfetto/distinfo
@@ -1,25 +1,17 @@
-TIMESTAMP = 1783544597
+TIMESTAMP = 1783610442
SHA256 (sqlite-amalgamation-3500300.zip) = 9ad6d16cbc1df7cd55c8b55127c82a9bca5e9f287818de6dc87e04e73599d754
SIZE (sqlite-amalgamation-3500300.zip) = 2845433
SHA256 (llvm-project-617a15a9eac96088ae5e9134248d8236e34b91b1.tgz) = 7e2541446a27f2a09a84520da7bc93cd71749ba0f17318f2d5291fbf45b97956
SIZE (llvm-project-617a15a9eac96088ae5e9134248d8236e34b91b1.tgz) = 83475
-SHA256 (google-perfetto-v54.0_GH0.tar.gz) = 8a6144d81592e00fb9e75da42483a2544315b25e3113845505d69950083913c1
-SIZE (google-perfetto-v54.0_GH0.tar.gz) = 49105061
+SHA256 (google-perfetto-v57.2_GH0.tar.gz) = 99469718d2e531bff7a33c7ee03a99ddc0f3710be5b4f744bd41d3794df274ab
+SIZE (google-perfetto-v57.2_GH0.tar.gz) = 58661586
SHA256 (protocolbuffers-protobuf-v31.1_GH0.tar.gz) = c3a0a9ece8932e31c3b736e2db18b1c42e7070cd9b881388b26d01aa71e24ca2
SIZE (protocolbuffers-protobuf-v31.1_GH0.tar.gz) = 9602477
SHA256 (abseil-abseil-cpp-20250512.1_GH0.tar.gz) = 9b7a064305e9fd94d124ffa6cc358592eb42b5da588fb4e07d09254aa40086db
SIZE (abseil-abseil-cpp-20250512.1_GH0.tar.gz) = 2221441
SHA256 (sqlite-sqlite-version-3.50.3_GH0.tar.gz) = ced5a0e1928b8851f5f2176a521241ac42746233b5cd02341c1d9fa40d5ca222
SIZE (sqlite-sqlite-version-3.50.3_GH0.tar.gz) = 12992292
+SHA256 (google-re2-927f5d53caf8111721e734cf24724686bb745f55_GH0.tar.gz) = 8635bc46ac8d73974b4198229805287c8d620245f2081af155d7d96d4988a3a5
+SIZE (google-re2-927f5d53caf8111721e734cf24724686bb745f55_GH0.tar.gz) = 397888
SHA256 (libexpat-libexpat-R_2_6_2_GH0.tar.gz) = fbd032683370d761ba68dba2566d3280a154f5290634172d60a79b24d366d9dc
SIZE (libexpat-libexpat-R_2_6_2_GH0.tar.gz) = 8416128
-SHA256 (0a47f21e97615e0259dcb8589190aa0912c47bbe.patch) = 7aa9dfbe2ee1509b1253859681b34efa135419c51a9f17be817e6e0735d531d5
-SIZE (0a47f21e97615e0259dcb8589190aa0912c47bbe.patch) = 1432
-SHA256 (d400ae17f63c91846fb489dc716109fbfac311a4.patch) = 6881cd5790888fedb4f8894c1cccd21e9b3876249ef0823a77593af0fdcbb0e7
-SIZE (d400ae17f63c91846fb489dc716109fbfac311a4.patch) = 20290
-SHA256 (0e50ef0b9372580b18c2693a1f4a95cb8ee8abc7.patch) = bb89d2358c9299b5c4a387f685565c20ef878b5eb476f211350f7d226a8b5a3d
-SIZE (0e50ef0b9372580b18c2693a1f4a95cb8ee8abc7.patch) = 19299
-SHA256 (6620157cb2a8cf3334219fce26cd91d8089a8cd2.patch) = 4a0929ceea5ac478d69e56282100c44f839add744ccbcf81c2ee92a1847c84b4
-SIZE (6620157cb2a8cf3334219fce26cd91d8089a8cd2.patch) = 2159
-SHA256 (1b24730762d082dae073f096d5e666e0fc83a1bb.patch) = 085452de9e97cfe272f6bc0ca6d8842009f2b6ce7ad08eaa9e8b8e40971185c5
-SIZE (1b24730762d082dae073f096d5e666e0fc83a1bb.patch) = 22460
diff --git a/devel/perfetto/files/patch-BUILD.gn b/devel/perfetto/files/patch-BUILD.gn
new file mode 100644
index 000000000000..5f6d418c27d2
--- /dev/null
+++ b/devel/perfetto/files/patch-BUILD.gn
@@ -0,0 +1,12 @@
+--- BUILD.gn.orig 2026-07-07 14:09:45 UTC
++++ BUILD.gn
+@@ -140,6 +140,9 @@ if (enable_perfetto_integration_tests) {
+ all_targets += [
+ "examples/shared_lib:example_shlib_data_source",
+ "examples/shared_lib:example_shlib_track_event",
++ "examples/dtrace:dtrace_probe",
++ "examples/freebsd:freebsd_power",
++ "examples/freebsd:freebsd_sys",
+ ]
+ }
+ }
diff --git a/devel/perfetto/files/patch-examples_dtrace_BUILD.gn b/devel/perfetto/files/patch-examples_dtrace_BUILD.gn
new file mode 100644
index 000000000000..c69806f9616d
--- /dev/null
+++ b/devel/perfetto/files/patch-examples_dtrace_BUILD.gn
@@ -0,0 +1,36 @@
+--- examples/dtrace/BUILD.gn.orig 2026-07-09 15:43:01 UTC
++++ examples/dtrace/BUILD.gn
+@@ -0,0 +1,33 @@
++# Copyright (C) 2022 The Android Open Source Project
++#
++# Licensed under the Apache License, Version 2.0 (the "License");
++# you may not use this file except in compliance with the License.
++# You may obtain a copy of the License at
++#
++# http://www.apache.org/licenses/LICENSE-2.0
++#
++# Unless required by applicable law or agreed to in writing, software
++# distributed under the License is distributed on an "AS IS" BASIS,
++# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++# See the License for the specific language governing permissions and
++# limitations under the License.
++
++# On windows C11 (required for atomics) is not really supported, so we can't
++# really build a C executable.
++assert(!is_win)
++
++executable("dtrace_probe") {
++ testonly = true
++ deps = [
++ "../../gn:default_deps",
++ "../../src/shared_lib:libperfetto_c",
++ ]
++ libs = [
++ "dtrace",
++ "sbuf",
++ ]
++ sources = [
++ "dtrace_probe.c",
++ ]
++}
++
diff --git a/devel/perfetto/files/patch-examples_dtrace_dtrace__probe.c b/devel/perfetto/files/patch-examples_dtrace_dtrace__probe.c
new file mode 100644
index 000000000000..4b188c026bcf
--- /dev/null
+++ b/devel/perfetto/files/patch-examples_dtrace_dtrace__probe.c
@@ -0,0 +1,416 @@
+--- examples/dtrace/dtrace_probe.c.orig 2026-07-09 15:43:01 UTC
++++ examples/dtrace/dtrace_probe.c
+@@ -0,0 +1,413 @@
++/*
++ * Copyright (C) 2026 The FreeBSD Foundation
++ *
++ * Portions of this file were written by Tom Jones (thj@freebsd.org) under
++ * sponsorship from The FreeBSD Foundation.
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++
++#include <err.h>
++#include <errno.h>
++#include <time.h>
++#include <unistd.h>
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <dtrace.h>
++#include <sys/sysctl.h>
++#include <assert.h>
++
++#include <sys/types.h>
++#include <sys/sbuf.h>
++
++#include "perfetto/public/data_source.h"
++#include "perfetto/public/producer.h"
++#include "perfetto/public/pb_decoder.h"
++//#include "perfetto/public/protos/trace/system_info/cpu_info.pbzero.h"
++//#include "perfetto/public/protos/trace/sys_stats/sys_stats.pbzero.h"
++
++#include "perfetto/public/track_event.h"
++
++#define DTRACE_CONFIG 143
++#define DTRACE_CONFIG_FBT_PROBE 1
++#define DTRACE_CONFIG_KINST_PROBE 2
++
++struct dtrace_context {
++ dtrace_hdl_t *g_dtp;
++ struct sbuf *program_text;
++ dtrace_prog_t *program;
++ struct PerfettoTeRegisteredTrack *tracks;
++ bool setupandrunning;
++ uint32_t fbt_events;
++ uint32_t kinst_events;
++};
++
++static struct PerfettoDs custom = PERFETTO_DS_INIT();
++
++static uint64_t get_current_time_ns(void) {
++ struct timespec ts;
++
++ (void)clock_gettime(CLOCK_BOOTTIME, &ts);
++
++ return (((uint64_t)ts.tv_sec * 1000000000ULL) + ts.tv_nsec);
++}
++
++static void
++dfail(dtrace_hdl_t *g_dtp, const char *message, ...)
++{
++ va_list args;
++ va_start(args, message);
++ (void) fprintf(stderr, "dtrace_probe: ");
++ (void) vfprintf(stderr, message, args);
++ va_end(args);
++ (void) fprintf(stderr, ": %s %d\n",
++ dtrace_errmsg(g_dtp, dtrace_errno(g_dtp)), dtrace_errno(g_dtp));
++ exit(2);
++}
++
++static void * dtrace_on_setup_cb(struct PerfettoDsImpl *impl,
++ PerfettoDsInstanceIndex inst_id, void *ds_config,
++ size_t ds_config_size, void* user_arg, struct PerfettoDsOnSetupArgs *args) {
++
++ (void)impl;
++ (void)inst_id;
++ (void)args;
++
++ int err;
++ struct dtrace_context *dctx = (struct dtrace_context *)user_arg;
++ int probes = 0;
++
++ dctx->program_text = sbuf_new_auto();
++ for (struct PerfettoPbDecoderIterator it =
++ PerfettoPbDecoderIterateBegin(ds_config, ds_config_size);
++ it.field.status == PERFETTO_PB_DECODER_OK;
++ PerfettoPbDecoderIterateNext(&it)) {
++ if (it.field.wire_type == 2 && it.field.id == DTRACE_CONFIG) {
++ struct PerfettoPbDecoderDelimitedField *dval = &it.field.value.delimited;
++
++ for (struct PerfettoPbDecoderIterator dit =
++ PerfettoPbDecoderIterateNestedBegin(*dval);
++ dit.field.status == PERFETTO_PB_DECODER_OK;
++ PerfettoPbDecoderIterateNext(&dit)) {
++ if (dit.field.wire_type == 2) {
++
++ struct PerfettoPbDecoderDelimitedField *p = &dit.field.value.delimited;
++ switch (dit.field.id) {
++ case DTRACE_CONFIG_FBT_PROBE:
++
++ /* entry probe */
++ sbuf_printf(dctx->program_text, "fbt:kernel:");
++ sbuf_bcat(dctx->program_text, p->start, p->len);
++ sbuf_printf(dctx->program_text, ":entry\n");
++
++ probes++;
++
++ /* return probe */
++ sbuf_printf(dctx->program_text, "fbt:kernel:");
++ sbuf_bcat(dctx->program_text, p->start, p->len);
++ sbuf_printf(dctx->program_text, ":return\n");
++
++ probes++;
++ break;
++ case DTRACE_CONFIG_KINST_PROBE:
++
++ /*
++ * instruction probe
++ * This can be a blank cheque
++ * to add inst probes to the
++ * kernel, but I can't see an
++ * option that is less flexible
++ * being useful.
++ */
++ sbuf_printf(dctx->program_text, "kinst::");
++ sbuf_bcat(dctx->program_text, p->start, p->len);
++ sbuf_printf(dctx->program_text, "\n");
++
++ probes++;
++
++ break;
++ default:
++ printf("unsupported config type %d!\n", dit.field.id);
++ break;
++ }
++ }
++ }
++ }
++ }
++ sbuf_finish(dctx->program_text);
++ printf("Installed %d probes\n", probes);
++ printf("---------- dtrace program --------------------\n");
++ sbuf_putbuf(dctx->program_text);
++ printf("----------------------------------------------\n\n");
++
++ if ((dctx->g_dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) {
++ printf("failed to initialize dtrace: %s\n",
++ dtrace_errmsg(NULL, err));
++ exit(1);
++ }
++
++ /*
++ * If we don't set a bufsize we will immediately get a failure due to
++ * buffer exhaustion.
++ */
++ if (dtrace_setopt(dctx->g_dtp, "bufsize", "10M") == -1)
++ dfail(dctx->g_dtp, "failed to set 'bufsize'");
++
++ if (dtrace_setopt(dctx->g_dtp, "bufpolicy", "switch") == -1)
++ dfail(dctx->g_dtp, "failed to set buffer policy 'switch'");
++
++ if ((dctx->program = dtrace_program_strcompile(dctx->g_dtp,
++ sbuf_data(dctx->program_text), DTRACE_PROBESPEC_NAME, 0, 0, NULL)) == NULL) {
++ dfail(dctx->g_dtp, "failed to compile program");
++ exit(1);
++ }
++
++ dtrace_proginfo_t info;
++ if (dtrace_program_exec(dctx->g_dtp, dctx->program, &info) == -1) {
++ dfail(dctx->g_dtp, "failed to enable probes");
++ exit(1);
++ }
++
++ if (dtrace_go(dctx->g_dtp) != 0) {
++ dfail(dctx->g_dtp, "couldn't start tracing\n");
++ exit(1);
++ }
++
++ /*
++ * Set up a track for each cpu .
++ * XXX: TODO hardcode my cores (nproc=16)
++ */
++ struct PerfettoTeRegisteredTrack *cpu_tracks =
++ calloc(sizeof(struct PerfettoTeRegisteredTrack), 16);
++ dctx->tracks = cpu_tracks;
++ for (int i = 0; i < 16; i++) {
++
++ struct sbuf *name = sbuf_new_auto();
++
++ sbuf_printf(name, "CPU %d", i);
++ sbuf_finish(name);
++// printf("registering uuid \t%s\n", sbuf_data(name));
++ PerfettoTeNamedTrackRegister(cpu_tracks, sbuf_data(name),
++ i, PerfettoTeGlobalTrackUuid(), true);
++// printf("uuid %lx\n", cpu_tracks->impl.uuid);
++ sbuf_delete(name);
++ cpu_tracks++;
++ }
++
++
++ /*
++ * XXX: We end up with both inst_ctx and user arg being the same struct
++ * dtrace_context *.
++ */
++ return (void *)dctx;
++
++}
++
++static void dtrace_on_start_cb(struct PerfettoDsImpl* impl,
++ PerfettoDsInstanceIndex inst_id, void* user_arg,
++ void* inst_ctx, struct PerfettoDsOnStartArgs* args) {
++
++ (void)impl;
++ (void)inst_id;
++ (void)inst_ctx;
++ (void)args;
++
++ struct dtrace_context *dctx = (struct dtrace_context *)user_arg;
++ dctx->setupandrunning = true;
++}
++
++static void dtrace_on_stop_cb(struct PerfettoDsImpl *impl,
++ PerfettoDsInstanceIndex inst_id, void* user_arg, void* inst_ctx,
++ struct PerfettoDsOnStopArgs* args) {
++
++ (void)impl;
++ (void)inst_id;
++ (void)user_arg;
++ (void)inst_ctx;
++ (void)args;
++
++
++ struct dtrace_context *dctx = (struct dtrace_context *)user_arg;
++
++ printf("%s\tfbt events: %u kinst events: %u\n", __func__, dctx->fbt_events, dctx->kinst_events);
++
++ dctx->setupandrunning = false;
++ dtrace_stop(dctx->g_dtp);
++
++ dctx->program = NULL;
++ sbuf_delete(dctx->program_text);
++
++ struct PerfettoTeRegisteredTrack *tracks = dctx->tracks;
++ for (int i = 0; i < 16; i++) {
++ PerfettoTeRegisteredTrackUnregister(tracks);
++ tracks++;
++ }
++
++ free(dctx->tracks);
++ dctx->tracks = NULL;
++
++}
++
++static void dtrace_on_destroy_cb(struct PerfettoDsImpl *impl,
++ void* user_arg, void* inst_ctx) {
++
++ (void)impl;
++ (void)user_arg;
++ (void)inst_ctx;
++
++ printf("%s\n", __func__);
++}
++
++static int
++process_record(const dtrace_probedata_t *data, const dtrace_recdesc_t *rec, void *arg)
++{
++ (void)rec;
++
++ struct dtrace_context *dctx = (struct dtrace_context *)arg;
++
++ dtrace_probedesc_t *pd = data->dtpda_pdesc;
++ processorid_t cpu = data->dtpda_cpu;
++ uint64_t track_uuid;
++#if 0
++ printf("%3d uuid 0x%lx ts %zd str %s %s:%s\n",
++ cpu, track_uuid, data->dtpda_timestamp,
++ sbuf_data(tn), pd->dtpd_func, pd->dtpd_name);
++#endif
++ //uintptr_t addr;
++#if 0
++ dtrace_actkind_t act;
++ if (rec == NULL) {
++ return (DTRACE_CONSUME_NEXT);
++ }
++ act = rec->dtrd_action;
++printf("%s:%d\n", __func__, __LINE__);
++ //addr = (uintptr_t)data->dtpda_data;
++ if (act == DTRACEACT_EXIT) {
++ //g_status = *((uint32_t *)addr);
++ return (DTRACE_CONSUME_NEXT);
++ }
++#endif
++ PERFETTO_DS_TRACE(custom, ctx) {
++ struct PerfettoDsRootTracePacket root;
++ PerfettoDsTracerPacketBegin(&ctx, &root);
++
++ /* XXX: this is a free running nanotime counter from "some point in time" */
++ perfetto_protos_TracePacket_set_timestamp(&root.msg, get_current_time_ns());
++
++ perfetto_protos_TracePacket_set_timestamp(&root.msg, data->dtpda_timestamp);
++ //perfetto_protos_TracePacket_set_timestamp_clock_id(&root.msg, XXX);
++
++ {
++ struct perfetto_protos_TrackEvent te;
++ perfetto_protos_TracePacket_begin_track_event(&root.msg, &te);
++
++ /* Set track name */
++ /* XXX: TODO This should be an internened track name */
++ struct sbuf *tn = sbuf_new_auto();
++
++ sbuf_printf(tn, "CPU %d", cpu);
++ sbuf_finish(tn);
++ track_uuid = PerfettoTeNamedTrackUuid(sbuf_data(tn), cpu,
++ PerfettoTeGlobalTrackUuid());
++ perfetto_protos_TrackEvent_set_name(&te, sbuf_data(tn), sbuf_len(tn));
++ //perfetto_protos_TrackEvent_set_name_iid(&te, cpu);
++ sbuf_delete(tn);
++
++ perfetto_protos_TrackEvent_set_track_uuid(&te, track_uuid);
++ perfetto_protos_TrackEvent_set_timestamp_absolute_us(&te, data->dtpda_cpu/1000);
++
++ struct sbuf *cat = sbuf_new_auto();
++ sbuf_printf(cat, "%s:%s", pd->dtpd_provider, pd->dtpd_func);
++ sbuf_finish(cat);
++ perfetto_protos_TrackEvent_set_categories(&te, sbuf_data(cat), sbuf_len(cat));
++ sbuf_delete(cat);
++
++#define TYPE_UNSPECIFIED 0
++#define TYPE_SLICE_BEGIN 1
++#define TYPE_SLICE_END 2
++#define TYPE_INSTANT 3
++#define TYPE_COUNTER 4
++
++ if(strcmp(pd->dtpd_provider, "kinst") == 0) {
++ dctx->kinst_events++;
++ perfetto_protos_TrackEvent_set_type(&te, TYPE_INSTANT);
++ } else if(strcmp(pd->dtpd_provider, "fbt") == 0) {
++ dctx->fbt_events++;
++ if (strcmp(pd->dtpd_name, "entry") == 0)
++ perfetto_protos_TrackEvent_set_type(&te, TYPE_SLICE_BEGIN);
++ else
++ perfetto_protos_TrackEvent_set_type(&te, TYPE_SLICE_END);
++ }
++ perfetto_protos_TracePacket_end_track_event(&root.msg, &te);
++ }
++
++ PerfettoDsTracerPacketEnd(&ctx, &root);
++// PerfettoDsTracerFlush(&ctx, NULL, NULL);
++ }
++ return (DTRACE_CONSUME_THIS);
++}
++
++int main(void) {
++ struct PerfettoProducerInitArgs args = PERFETTO_PRODUCER_INIT_ARGS_INIT();
++ struct PerfettoDsParams ds_params;
++ struct dtrace_context dctx;
++
++ args.backends = PERFETTO_BACKEND_SYSTEM;
++ PerfettoProducerInit(args);
++
++ /* Initialise the default parameters */
++ ds_params = PerfettoDsParamsDefault();
++
++ /* Life cycle call backs */
++ ds_params.on_start_cb = dtrace_on_start_cb;
++ ds_params.on_setup_cb = dtrace_on_setup_cb;
++ ds_params.on_stop_cb = dtrace_on_stop_cb;
++ ds_params.on_destroy_cb = dtrace_on_destroy_cb;
++ ds_params.user_arg = &dctx;
++
++ PerfettoDsRegister(&custom, "dtrace", ds_params);
++
++ /*
++ * XXX: TODO We should check priviliges here before trying to create dtrace
++ * probs later when we are setup and configured
++ */
++
++ /* Sit in a loop */
++ for (;;) {
++ /*
++ * If we aren't running sleep for 250 mS, that puts some extra
++ * latency on start, but will be fine for testing.
++ */
++ if (!dctx.setupandrunning) {
++ usleep(250 * 1000);
++ continue;
++ }
++
++ /*
++ * dtrace work loop
++ */
++ switch (dtrace_work(dctx.g_dtp, stdout, NULL, process_record, &dctx)) {
++ case DTRACE_WORKSTATUS_DONE:
++ //done = 1;
++ break;
++ case DTRACE_WORKSTATUS_OKAY:
++ break;
++ default:
++ if (dtrace_errno(dctx.g_dtp) != EINTR)
++ dfail(dctx.g_dtp, "processing aborted");
++ }
++
++ dtrace_sleep(dctx.g_dtp);
++ }
++}
diff --git a/devel/perfetto/files/patch-examples_dtrace_examples_dtrace__probes.cfg b/devel/perfetto/files/patch-examples_dtrace_examples_dtrace__probes.cfg
new file mode 100644
index 000000000000..91cee4601d0c
--- /dev/null
+++ b/devel/perfetto/files/patch-examples_dtrace_examples_dtrace__probes.cfg
@@ -0,0 +1,21 @@
+--- examples/dtrace/examples/dtrace_probes.cfg.orig 2026-07-09 15:43:01 UTC
++++ examples/dtrace/examples/dtrace_probes.cfg
+@@ -0,0 +1,18 @@
++buffers: {
++ size_kb: 8960
++ fill_policy: DISCARD
++}
++
++data_sources: {
++ config {
++ name: "dtrace"
++ dtrace_config {
++ dtrace_fbt_probe: "udp_send"
++# dtrace_fbt_probe: "tcp_output"
++# dtrace_kinst_probe: "amd64_syscall:"
++ dtrace_kinst_probe: "udp_input:"
++ }
++ }
++}
++
++duration_ms: 1000000
diff --git a/devel/perfetto/files/patch-examples_freebsd_BUILD.gn b/devel/perfetto/files/patch-examples_freebsd_BUILD.gn
new file mode 100644
index 000000000000..ba71c63199a8
--- /dev/null
+++ b/devel/perfetto/files/patch-examples_freebsd_BUILD.gn
@@ -0,0 +1,52 @@
+--- examples/freebsd/BUILD.gn.orig 2026-07-09 15:43:01 UTC
++++ examples/freebsd/BUILD.gn
+@@ -0,0 +1,49 @@
++# Copyright (C) 2022 The Android Open Source Project
++#
++# Licensed under the Apache License, Version 2.0 (the "License");
++# you may not use this file except in compliance with the License.
++# You may obtain a copy of the License at
++#
++# http://www.apache.org/licenses/LICENSE-2.0
++#
++# Unless required by applicable law or agreed to in writing, software
++# distributed under the License is distributed on an "AS IS" BASIS,
++# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++# See the License for the specific language governing permissions and
++# limitations under the License.
++
++# On windows C11 (required for atomics) is not really supported, so we can't
++# really build a C executable.
++assert(!is_win)
++
++executable("freebsd_power") {
++ testonly = true
++ deps = [
++ "../../gn:default_deps",
++ "../../src/shared_lib:libperfetto_c",
++ ]
++ libs = [
++ "sbuf",
++ ]
++ sources = [
++ "power.c",
++ ]
++}
++
++executable("freebsd_sys") {
++ testonly = true
++ deps = [
++ "../../gn:default_deps",
++ "../../src/shared_lib:libperfetto_c",
++ ]
++ libs = [
++ "geom",
++ "devstat",
++ ]
++ sources = [
++ "freebsd_sys_stats.c",
++ "freebsd_sys_stats_cpu.c",
++ "freebsd_sys_stats_disk.c",
++ "freebsd_sys_stats_intr.c",
++ ]
++}
diff --git a/devel/perfetto/files/patch-examples_freebsd_examples_power.cfg b/devel/perfetto/files/patch-examples_freebsd_examples_power.cfg
new file mode 100644
index 000000000000..6e49a9ef89f2
--- /dev/null
+++ b/devel/perfetto/files/patch-examples_freebsd_examples_power.cfg
@@ -0,0 +1,15 @@
+--- examples/freebsd/examples/power.cfg.orig 2026-07-09 15:43:01 UTC
++++ examples/freebsd/examples/power.cfg
+@@ -0,0 +1,12 @@
++buffers: {
++ size_kb: 8960
++ fill_policy: DISCARD
++}
++
++data_sources: {
++ config {
++ name: "freebsd.power"
++ }
++}
++
++duration_ms: 10000
diff --git a/devel/perfetto/files/patch-examples_freebsd_freebsd__sys__stats.c b/devel/perfetto/files/patch-examples_freebsd_freebsd__sys__stats.c
new file mode 100644
index 000000000000..b636ec709254
--- /dev/null
+++ b/devel/perfetto/files/patch-examples_freebsd_freebsd__sys__stats.c
@@ -0,0 +1,99 @@
+--- examples/freebsd/freebsd_sys_stats.c.orig 2026-07-09 15:43:01 UTC
++++ examples/freebsd/freebsd_sys_stats.c
+@@ -0,0 +1,96 @@
++/*
++ * Copyright (C) 2022 The Android Open Source Project
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++
++#include <err.h>
++#include <errno.h>
++#include <time.h>
++#include <unistd.h>
++
++#include <devstat.h>
++#include <libgeom.h>
++#include <stdio.h>
++#include <sys/sysctl.h>
++
++#include "perfetto/public/data_source.h"
++#include "perfetto/public/producer.h"
++#include "perfetto/public/protos/trace/sys_stats/sys_stats.pzc.h"
++#include "perfetto/public/protos/trace/trace_packet.pzc.h"
++
++extern void setup_intrcnt_data(void);
++extern void populate_intrcnt_data(struct perfetto_protos_SysStats* sys_stat);
++
++extern void setup_disk_data(void);
++extern void populate_disk_data(struct perfetto_protos_SysStats* sys_stat);
++
++extern void setup_cpu_data(void);
++extern void populate_cpu_data(struct perfetto_protos_SysStats* sys_stat);
++extern void populate_cpu_freq_data(struct perfetto_protos_SysStats* sys_stat);
++extern void populate_cpu_freq_idle(struct perfetto_protos_SysStats* sys_stat);
++
++static struct PerfettoDs custom = PERFETTO_DS_INIT();
++
++static uint64_t get_current_time_ns(void) {
++ struct timespec ts;
++
++ (void)clock_gettime(CLOCK_BOOTTIME, &ts);
++
++ return (((uint64_t)ts.tv_sec * 1000000000ULL) + ts.tv_nsec);
++}
++
++int main(void) {
++ struct PerfettoProducerInitArgs args = PERFETTO_PRODUCER_INIT_ARGS_INIT();
++ args.backends = PERFETTO_BACKEND_SYSTEM;
++ PerfettoProducerInit(args);
++
++ /* GEOM for disk stats */
++ setup_disk_data();
++
++ /* intr setup */
++ setup_intrcnt_data();
++
++ /* cpu setup */
++ setup_cpu_data();
++
++ PerfettoDsRegister(&custom, "freebsd.sys_stats", PerfettoDsParamsDefault());
++
++ for (;;) {
++ PERFETTO_DS_TRACE(custom, ctx) {
++ struct PerfettoDsRootTracePacket root;
++ PerfettoDsTracerPacketBegin(&ctx, &root);
++
++ perfetto_protos_TracePacket_set_timestamp(&root.msg,
++ get_current_time_ns());
++ {
++ struct perfetto_protos_SysStats sys_stats;
++
++ perfetto_protos_TracePacket_begin_sys_stats(&root.msg, &sys_stats);
++
++ populate_disk_data(&sys_stats);
++ populate_intrcnt_data(&sys_stats);
++ populate_cpu_data(&sys_stats);
++ populate_cpu_freq_data(&sys_stats);
++ populate_cpu_freq_idle(&sys_stats);
++
++ perfetto_protos_TracePacket_end_sys_stats(&root.msg, &sys_stats);
++ }
++ PerfettoDsTracerPacketEnd(&ctx, &root);
++ }
++ // 100ms sleep
++ usleep(100 * 1000);
++ // usleep(250 * 1000);
++ // sleep(1);
++ }
++}
diff --git a/devel/perfetto/files/patch-examples_freebsd_freebsd__sys__stats__cpu.c b/devel/perfetto/files/patch-examples_freebsd_freebsd__sys__stats__cpu.c
new file mode 100644
index 000000000000..0c6b3e2b9869
--- /dev/null
+++ b/devel/perfetto/files/patch-examples_freebsd_freebsd__sys__stats__cpu.c
@@ -0,0 +1,309 @@
+--- examples/freebsd/freebsd_sys_stats_cpu.c.orig 2026-07-09 15:43:01 UTC
++++ examples/freebsd/freebsd_sys_stats_cpu.c
+@@ -0,0 +1,306 @@
++/*
++ * Copyright (C) 2022 The Android Open Source Project
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++
++#include <err.h>
++#include <errno.h>
++#include <limits.h>
++#include <stdlib.h>
++#include <time.h>
++#include <unistd.h>
++
++#include <devstat.h>
++#include <libgeom.h>
++#include <stdio.h>
++#include <sys/resource.h>
++#include <sys/sysctl.h>
++
++#include "perfetto/public/data_source.h"
++#include "perfetto/public/producer.h"
++#include "perfetto/public/protos/trace/sys_stats/sys_stats.pzc.h"
++#include "perfetto/public/protos/trace/trace_packet.pzc.h"
++
++/*
++ * TODO:
++ *
++ * Don't keep reading the list of per-CPU C states each time;
++ * read them once during setup and store them globally!
++ *
++ * TODO: we only support 64 CPUs here (u_long mask)!
++ */
++
++struct {
++ int maxcpu;
++ long* times;
++ long* last_cp_times;
++ int times_size;
++ u_long mask;
++ int maxid;
++ bool have_prev; /* TODO: need to clear this between runs */
++} cpu_info;
++
++void setup_cpu_data(void) {
++ size_t size;
++ int ret;
++ int empty, i, j;
++
++ /* Figure out the maximum CPU id */
++ size = sizeof(int);
++ ret = sysctlbyname("kern.smp.maxcpus", &cpu_info.maxcpu, &size, NULL, 0);
++ if (ret != 0) {
++ printf("%s: kern.smp.maxcpus failed (%d)\n", __func__, ret);
++ return;
++ }
++
++ printf("maxcpu: %d\n", cpu_info.maxcpu);
++
++ /* Allocate cpu time array for current and previous cpu times */
++ cpu_info.times_size = sizeof(long) * cpu_info.maxcpu * CPUSTATES;
++ cpu_info.times = calloc(1, cpu_info.times_size);
++ cpu_info.last_cp_times = calloc(1, cpu_info.times_size);
++
++ /* Fetch a round of CPU stats, likely to figure out what's up */
++ size = cpu_info.times_size;
++ ret = sysctlbyname("kern.cp_times", cpu_info.times, &size, NULL, 0);
++ if (ret != 0) {
++ printf("%s: kern.cp_times failed (%d)\n", __func__, errno);
++ return;
++ }
++
++ /* figure out the maximum id */
++ cpu_info.maxid = (size / CPUSTATES / sizeof(long)) - 1;
++
++ for (i = 0; i <= cpu_info.maxid; i++) {
++ empty = 1;
++ for (j = 0; empty && j < CPUSTATES; j++) {
++ if (cpu_info.times[i * CPUSTATES + j] != 0)
++ empty = 0;
++ }
++ if (!empty)
++ cpu_info.mask |= (1ul << i);
++ }
++}
++
++static unsigned long fetch_cp_time_delta(int cpu, int which) {
++ unsigned long delta;
++
++ delta = cpu_info.times[cpu * CPUSTATES + which] -
++ cpu_info.last_cp_times[cpu * CPUSTATES + which];
++
++ delta = (delta * 1000000000ULL) / CLOCKS_PER_SEC;
++
++ return (delta);
++}
++
++void populate_cpu_data(struct perfetto_protos_SysStats* sys_stat) {
++ (void)sys_stat;
++ size_t size;
++ int ret, i;
++
++ size = cpu_info.times_size;
++ ret = sysctlbyname("kern.cp_times", cpu_info.times, &size, NULL, 0);
++ if (ret != 0) {
++ printf("%s: kern.cp_times failed (%d)\n", __func__, errno);
++ return;
++ }
++
++ if (cpu_info.have_prev == false)
++ goto skip;
++
++ for (i = 0; i <= cpu_info.maxid; i++) {
++ struct perfetto_protos_SysStats_CpuTimes cpu_cnt;
++ unsigned long delta;
++
++ if ((cpu_info.mask & (1ul << i)) == 0)
*** 1183 LINES SKIPPED ***