git: 7185635a576f - main - devel/perfetto: update to 57.2

From: Siva Mahadevan <siva_at_FreeBSD.org>
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 ***