Issue #75: attributable, actionable DTrace profiles #90

Merged
ober merged 39 commits from fix/issue-75-attributable-traces into master 2026-09-22 00:52:31 -04:00
Owner

Issue #75: attributable, actionable DTrace profiles

Closes #75.

What

End-to-end DTrace measurement pipeline: capture -> validated bundle -> actionable reports, plus the overhead bench harness and attribution workload.

Capture and bundle (steps 1-2)

  • tools/dtrace/capture.sh: live FreeBSD capture producing a self-contained bundle (retained binary, argv, cohort identity, six raw families, checksums, atomic publish with INCOMPLETE fail-closed staging).
  • support/dtrace/process-identity.c: native process incarnation identity (boot_id/pid/start_ns) for attributable cohorts; FreeBSD fix (sys/user.h include).
  • Cohort model (tools/dtrace/cohort.ss): helper-backed identity, sealed cohorts, readiness gates; fixed a Gerbil-only untaint in the identity parse found by live capture.
  • Validators and collectors hardened against real FreeBSD dtrace semantics found during live verification:
    • probe specs must use hyphen display names (allocation-sample, not allocation__sample)
    • USDT family gating and readiness must query exact probes: FreeBSD's pid provider lists every process function under any invented provider<pid> name, and dtrace -l exits 0 with zero matches
    • wait for USDT DOF registration before SIGSTOP, serialize collector grabs, escalate INT->TERM->KILL for backgrounded dtrace
    • D language fixes: no top-level assignments, no void* arithmetic, copyin takes uintptr_t, cpu collector records frame unknown (profile probes forbid func as a scalar; usym/ustack cannot be stringified)
    • 16m gc buffers (1M+ pause floods dropped records at 4m)

Reports (step 3)

  • tools/dtrace/report.ss: report.json/report.md/cpu.folded/syscalls.csv/io.csv/allocations.csv/gc.csv/spans.csv from any bundle; complete = verdict pass && malformed=0; fail-closed integration into capture finalize (stub -> validate run1 -> real reports -> regen sums -> final validate -> publish).

Benchmarks and attribution (2g)

  • benchmarks/dtrace/bench-overhead.ss with control lines, attach barrier, startup/elapsed split; bench-settings.env single source of truth; run-overhead.sh A/B driver (4 modes, alternating order, absolute binary paths); compare-overhead.sh gated comparison engine; deterministic attribution.ss workload (index-build/validate/io-overlap phases with user-event markers and io probes).
  • syscalls-freebsd.d: flock/ioctl/dup2 probes.

Validation fixes found by live verification

  • empty bundle members hashed as missing (get-bytevector-all returns eof for empty files) -> universal checksum mismatches; syscall fd/request/ret now accept signed integers (openat AT_FDCWD dirfd).

Verification

  • make test-dtrace-unit green on macOS (78 PASS) and FreeBSD biggus (gmake DTRACE=on DTRACE_REQUIRED=1 test-dtrace-unit, 196 PASS lines).
  • Live end-to-end on FreeBSD 15.1 (biggus, dtraceall loaded): six collectors attached serially, capture.sh --preset full published a validated bundle (rc=0), validate.ss rc=0, report.ss rc=0 report: complete (pass); gc.csv pause_count=60046, aggregated syscalls, cpu samples, control events present.
  • make binary clean; jerboa-bin --version 0.13.0; VERSION bumped per policy.
  • Cookbook entries for the FreeBSD dtrace lessons added to data/howtos.sexp.
# Issue #75: attributable, actionable DTrace profiles Closes #75. ## What End-to-end DTrace measurement pipeline: capture -> validated bundle -> actionable reports, plus the overhead bench harness and attribution workload. ### Capture and bundle (steps 1-2) - `tools/dtrace/capture.sh`: live FreeBSD capture producing a self-contained bundle (retained binary, argv, cohort identity, six raw families, checksums, atomic publish with INCOMPLETE fail-closed staging). - `support/dtrace/process-identity.c`: native process incarnation identity (boot_id/pid/start_ns) for attributable cohorts; FreeBSD fix (`sys/user.h` include). - Cohort model (`tools/dtrace/cohort.ss`): helper-backed identity, sealed cohorts, readiness gates; fixed a Gerbil-only `untaint` in the identity parse found by live capture. - Validators and collectors hardened against real FreeBSD dtrace semantics found during live verification: - probe specs must use hyphen display names (`allocation-sample`, not `allocation__sample`) - USDT family gating and readiness must query exact probes: FreeBSD's pid provider lists every process function under any invented `provider<pid>` name, and `dtrace -l` exits 0 with zero matches - wait for USDT DOF registration before SIGSTOP, serialize collector grabs, escalate INT->TERM->KILL for backgrounded dtrace - D language fixes: no top-level assignments, no `void*` arithmetic, `copyin` takes `uintptr_t`, cpu collector records frame `unknown` (profile probes forbid `func` as a scalar; `usym`/`ustack` cannot be stringified) - 16m gc buffers (1M+ pause floods dropped records at 4m) ### Reports (step 3) - `tools/dtrace/report.ss`: report.json/report.md/cpu.folded/syscalls.csv/io.csv/allocations.csv/gc.csv/spans.csv from any bundle; complete = verdict pass && malformed=0; fail-closed integration into capture finalize (stub -> validate run1 -> real reports -> regen sums -> final validate -> publish). ### Benchmarks and attribution (2g) - `benchmarks/dtrace/bench-overhead.ss` with control lines, attach barrier, startup/elapsed split; `bench-settings.env` single source of truth; `run-overhead.sh` A/B driver (4 modes, alternating order, absolute binary paths); `compare-overhead.sh` gated comparison engine; deterministic `attribution.ss` workload (index-build/validate/io-overlap phases with user-event markers and io probes). - `syscalls-freebsd.d`: flock/ioctl/dup2 probes. ### Validation fixes found by live verification - empty bundle members hashed as missing (`get-bytevector-all` returns eof for empty files) -> universal checksum mismatches; syscall fd/request/ret now accept signed integers (openat AT_FDCWD dirfd). ## Verification - `make test-dtrace-unit` green on macOS (78 PASS) and FreeBSD biggus (`gmake DTRACE=on DTRACE_REQUIRED=1 test-dtrace-unit`, 196 PASS lines). - Live end-to-end on FreeBSD 15.1 (biggus, dtraceall loaded): six collectors attached serially, `capture.sh --preset full` published a validated bundle (rc=0), `validate.ss` rc=0, `report.ss` rc=0 `report: complete (pass)`; gc.csv pause_count=60046, aggregated syscalls, cpu samples, control events present. - `make binary` clean; `jerboa-bin --version` 0.13.0; VERSION bumped per policy. - Cookbook entries for the FreeBSD dtrace lessons added to `data/howtos.sexp`.
ober added 29 commits 2026-09-21 18:46:58 -04:00
- tools/dtrace/raw-schema.json: measurement-bundle contract v1 (layout,
  manifest/cohort/settings/capabilities/collectors JSON, raw record
  format with common ns-timestamped prefix, event pairing rules, exit
  contract)
- tools/dtrace/validate.ss: fail-closed bundle validator (SHA256SUMS
  coverage+integrity, manifest boundaries/clock units, cohort
  incarnation binding, collector lifecycle incl attach ack/exit/signal/
  drops/errors, per-producer clock monotonicity, ovf loss markers,
  span/io/gc pairing + parent graph, control ordering, syscall-open
  boundary tails, events_observed cross-check, artifact hashes, family
  state mapping); exit 0 only for a valid complete bundle; uses core
  sha256-bytevector (no crypto library imports) so it runs under
  bin/jerboa and jerboa-bin alike
- tools/dtrace/cohort.ss: cohort registry keyed by boot id + pid +
  native start_ns + runtime nonce (helper: support/dtrace/
  process-identity.c), synthetic mode for fixtures, USDT predicate and
  selector generation
- tests/fixtures/dtrace: make-good.sh (checked-in good bundle +
  drift detection), gen-variants.sh (15 bad variants, each isolating
  one failure property)
- tests/dtrace/test-bundle-validation.sh: good/copied/variant matrix;
  wired into make test-dtrace-unit; verified green on the repo wrapper
  and jerboa-bin bridge vehicle
dtrace.ss:
- %call-with-span rewritten over dynamic-wind: every entry into the
  dynamic extent opens a fresh segment span (same parent, tree-shaped);
  every exit closes it exactly once with outcome ok/error/cancel;
  continuation escape closes with cancel and reentry opens a new
  segment, so no span id is ever double-ended or left unmatched
- current-dtrace-context is now a thread parameter; spans opened by a
  worker cannot leak another thread's context
- new public capture/install API: dtrace-context-capture,
  dtrace-call-with-context; thread-context-wrap-hook installed at the
  end of the library (a mid-body top-level expression splits the Chez
  library body and unbinds forward references)

propagation sites:
- (std misc thread) thread-start! applies the hook in the creator and
  reinstalls the context in the child
- (std actor scheduler) scheduler-submit! wraps submitted tasks with
  the submitter's context
- (std async) spawn-async-task! propagates into task threads
- (std fiber) fiber-spawn wraps fiber bodies; the parameterize extent
  survives engine preemption/resumption

tests:
- test-spans: escape/reentry segment assertions (cancel outcome, new
  segment on reentry, ordering)
- new test-span-propagation (both vehicles: tier-2 exact-context via
  public API, tier-1 bridge-gated recorded parent linkage)
- new test-span-context-workers (repo vehicle: actor, fiber, nested
  actor->fiber exact-context checks)
- build.ss compiles (std actor scheduler) and (std fiber) to .so for
  the new tests; Makefile wires both test lists into test-dtrace-unit
Collectors rewritten as independent pid-scoped consumers emitting
raw-schema v1 TSV records (jerboa$1/chez$1 pid-suffixed providers plus
explicit pid == $1 predicates for kernel providers; no dtrace -p grab):

- gc-pause.d: gc-start/gc-done/gcpause ns records, pause > 0 guard
- allocation.d: alloc-sample 12-field records with sampling weight
  (est = raw*w >> 16) and runtime/span attribution from the trace
  context
- cpu.d: cpu-sample 97 Hz on-CPU frame sampling with whitespace-frame
  drop counter reported at END
- io.d: io-start/io-done with duration, bytes, errno from io_v1
- user-spans.d: span tree records plus the capture lifecycle control
  records (ready/attached/warmup-done/workload-start at BEGIN,
  workload-done from proc:::exit)
- syscalls-freebsd.d / -macos.d / -linux.d: new per-syscall
  latency/fd/path collectors (openat/open/read/write/close/fsync);
  errno recorded as 0 where the carry flag is not a stable arg

capture.sh rewritten as the bundle producer: SIGSTOP target for the
attach window, data-driven attach acknowledgement per collector,
resume and wait for workload exit (fail-closed), drain, SIGINT
collectors, then finalize per-collector raw files (syscalls path_label
sanitization anchored on the fixed record tail, stable (pid, ts)
sort), emit collectors/settings/capabilities/manifest/cohort JSON,
stub report and validation verdict, checksums, and a two-pass
validate.ss embed ending in a read-only published bundle.  Non-FreeBSD
hosts exit 77 SKIP.

Tests: new test-capture-finalize.sh covers the sanitization and sort
transforms; test-dtrace-unit gains a shell syntax gate for the dtrace
tooling.  README updated for the new capture model.

Verification: make test-dtrace-unit green (19 bundle-validation
checks, 10 finalize checks, span/spans/propagation/workers suites,
syntax gate); capture.sh --help and the macOS SKIP-77 path exercised.
FreeBSD live capture verification lands with the issue #75 step-2e/2f
biggus run.
Capability manifest (issue #75 capability 1):
- configure.sh: enabled verdict now requires the working C compiler
  (CC_OK) that was previously only diagnosed on --mode=on; the dtrace -h
  probe's exit status and stderr are preserved; manifest gains
  DTRACE_BIN, DTRACE_TOOL_VERSION, DTRACE_UID, DTRACE_SIP, DTRACE_CC_OK,
  DTRACE_PROBE_RC, DTRACE_PROBE_ERR, and DTRACE_ATTACH_RESULT
  (not_attempted: only a collector run may assert attached)
- doctor.sh: --json emits exactly one JSON object (DTRACE_MODE summary
  line moved to text mode); provider listing preserves per-command
  status and first stderr line instead of swallowing them; adds sip and
  attach_result facts
- jerboa_trace_capabilities: "registered" is now always "unknown"
  (compile-time linkage is reported separately as usdt_compiled); adds
  clock state (monotonic|degraded|unavailable) and clock_degraded
  counter; the monotonic clock fallback no longer substitutes wall-clock
  time - unavailability is counted and reported

Runtime identity (capability 3):
- jerboa_trace_runtime_id rekeys on process-incarnation change: a fork
  child with inherited memory gets a fresh id (forced store is safe in
  the single-threaded child) instead of aliasing the parent
- both runtimes mix a harness per-exec nonce from
  JERBOA_TRACE_RUNTIME_NONCE into the runtime id (unset changes
  nothing); documented in tools/dtrace/README.md
- dtrace.ss capabilities struct gains usdt-compiled, clock-name,
  clock-degraded accessors; test-api asserts the new fields

Tests: new tests/dtrace/test-identity.c fixture (stable in-process id,
fork rekey, parent unchanged, nonce accepted, honest capabilities JSON)
run by test-identity.sh in test-dtrace-unit; make binary clean; full
test-dtrace-unit green (42 PASS lines).

Verification evidence: standalone cc compile of the bridge exercised
capabilities JSON and fork rekey directly (child ids diverge across
repeated runs and under the nonce env); doctor.sh --json parsed as a
single JSON object by python3 on macOS; configure.sh auto/off and
--mode=on diagnostics exercised on Darwin.
The .skip-test-tools marker is created by test-tools.sh on non-FreeBSD
hosts; it was accidentally committed with the step 2e change.  Drop it
from the index and ignore tests/dtrace/.skip-* so runs never stage it
again.
report.ss: rewritten as the bundle summarizer. Reads manifest/settings/
validation plus the raw families, emits report.json, report.md, and
per-family extracts (cpu.folded flamegraph input, syscalls.csv, io.csv,
allocations.csv, gc.csv, spans.csv). complete = validation verdict pass
AND zero malformed records; prints a one-line verdict and exits 0 only
for a complete report. Short non-comment lines now count as malformed
(matching the validator), and header/comment lines never do.

capture.sh: --max-bytes bound (default 512 MiB, min 1 MiB, enforced
during collection, fail closed), private $output.staging.$$ assembly dir
under umask 077, atomic single-rename read-only publish with PUBLISHED
flag, INCOMPLETE marker in logs/capture.log on any abort, richer
artifacts manifest (binary captured + sha, debug_info/symbol_maps
not_captured with reasons, source_refs git revision + jerboa version).
Finalize now runs report.ss into the staging bundle after the first
validate embeds the real verdict, regenerates SHA256SUMS, and re-runs
validate over the published content: a bundle that cannot be summarized
must not publish.

tests: test-report.sh rewritten as a subprocess contract (good fixture
exits 0 with complete:true and all artifacts, fail verdict exits 1,
malformed record forces INCOMPLETE despite pass verdict, missing bundle
fails cleanly). New test-bundle-copy.sh: copied and tar-extracted
bundles revalidate standalone; one-byte corruption and missing manifest
are rejected. Both wired into test-dtrace-unit; suite green (165 PASS).
benchmarks: one settings file (bench-settings.env) now feeds every
overhead mode -- the historical untraced-gc-stress-1000 vs
traced-10000 mismatch is gone. run-overhead.sh runs the standard
modes (mode-off baseline, no-consumer, light-sampling, full-tracing)
on the instrumented binary, alternates normal/reversed mode order
across rounds (order recorded in environment.env), hashes the
settings file per participant, and delegates comparison to the new
compare-overhead.sh: per-pair (traced/no_consumer - 1)*100 with
median/min/max, negatives preserved, baseline-noise marking, exit-3
refusal on settings-hash mismatch, and AB-INVALID (never a
percentage) when runs or attach failed. The workload prints control
ready/attached/workload-start/workload-done boundaries, holds at a
BENCH_ATTACH_FILE readiness barrier (bounded) so consumers attach to
a quiescent target, and reports startup-ms separately from the
steady-state elapsed-ms used for comparisons.

New benchmarks/dtrace/attribution.ss: bounded workload with known
structure (dominant index-build phase, minor validate phase,
overlapping two-reader I/O phase), user-event phase markers, spans,
io probes, explicitly installed thread contexts (raw thread-start!
is not auto-propagated), and deterministic independent counters so
traced/untraced runs reconcile mechanically; temp file cleaned up
via unwind-protect.

syscalls-freebsd.d: flock/ioctl/dup2 entry/return records (fd=arg0,
request=arg1), completing the handoff's syscall set.

tests/dtrace/test-overhead.sh (wired into test-dtrace-unit): settings
parity + no hardcoded iteration counts, compare contract (refusal,
negatives, AB-INVALID), driver smoke on tiny settings (alternating
order + startup capture), attribution determinism + cleanup. Suite
green.
Public capabilities (span attribution, bundle contract + validator,
capture/report tooling, capability reporting) warrant a minor bump
per the repository version policy.
FreeBSD clang makes the implicit getenv declaration from the 2e nonce
change a hard int-to-pointer conversion error; macOS only warned.
The fake libfixture.so was swallowed by the global *.so ignore, so
fresh clones (FreeBSD biggus) saw a drifted fixture; macOS only
passed on an untracked leftover. Negate the ignore for fixture
bundles and commit the member.
FreeBSD hosts without a usable /proc/PID/file (biggus) fall back to
procstat -b to name the executable for artifacts retention.
Detect once whether $JERBOA takes a run subcommand (repo wrapper) or
the script directly (jerboa-bin) and route cohort/validate/report
through a jrun helper.
The repo wrapper rejects /dev/null as a script path, which made the
style probe misclassify it as the direct multicall binary under
capture.sh.
FreeBSD 15 clang rejects the incomplete kinfo_proc type from kvm.h
alone; the struct lives in sys/user.h.
The live FreeBSD capture exposed it: the ready step never ran under
synthetic fixtures and untaint is not bound in Jerboa.
D scalars are implicitly zero-initialized; a bare top-level
assignment is a compile error under the real FreeBSD dtrace.
FreeBSD rejects func as a scalar in profile probes, usym cannot be
stringified, and ustack keys render empty for static Chez binaries,
so v1 records frame unknown and keeps counts/attribution exact.
SIGSTOPing before the DOF registration lands leaves chez\$pid
invisible, so every grabbing collector fails to compile; poll the
provider read-only (bounded 10s) and fail with a precise message.
The FreeBSD D compiler rejects void* + int; cast to char* at every
offset into a copyin record. Also settle 0.3s after SIGSTOP so the
stop fully lands before collectors grab the target.
FreeBSD's pid provider rejects concurrent grabs of one process;
launch collectors one at a time behind the existing data-driven
attach ack (target is stopped, so nothing is lost).
FreeBSD's pid provider lists every process function under any
invented provider<pid> name, so a bare chez\$pid:::/jerboa\$pid:::
count always exceeds zero and unlinked providers (jerboa spans/io)
slip through as observed. Query one concrete probe per family.
FreeBSD pid-provider listings spoof bare provider queries, so wait
for the real allocation__sample probe before stopping the target;
backgrounded dtrace inherits ignored SIGINT, so escalate INT to TERM
to KILL when stopping collectors (normal path and cleanup).
dtrace -l exits 0 with zero matches, so the previous gate always
passed instantly and froze the target before its USDT DOF landed.
Exact-name listing and matching only work as allocation-sample /
user-span-start; the underscore form matches nothing on FreeBSD.
get-bytevector-all yields eof for empty files, so empty collector
logs hashed as missing and failed every checksum; syscall fd/
request/ret can be negative (openat AT_FDCWD dirfd, failed-call
-1 returns) and need a signed integer token check.
gc-stress at full tilt emits over a million pauses in ~14s and
4m principal buffers drop tens of thousands of records.
dtrace: cookbook entries for FreeBSD live-capture lessons
Some checks failed
required-ci / gerbil-compat (pull_request) Successful in 3m58s
version-policy / required (pull_request) Successful in 4m53s
required-ci / required (pull_request) Failing after 9m47s
dtrace / freebsd-usdt (pull_request) Failing after 9m50s
freebsd-required / required (pull_request) Successful in 11m56s
f13cfcd08d
dtrace: update target-isolation test to the bundle capture contract
Some checks failed
required-ci / gerbil-compat (pull_request) Successful in 4m3s
version-policy / required (pull_request) Successful in 5m0s
dtrace / freebsd-usdt (pull_request) Has been cancelled
required-ci / required (pull_request) Has been cancelled
freebsd-required / required (pull_request) Has been cancelled
c92a499431
The multi-collector rewrite scopes probes via pid-suffixed
providers and dollar-one predicates instead of dtrace -p, and
incarnation binding moved from the old sidecar note into cohort
members plus per-raw inc header lines.
dtrace: port operator tools test to the bundle capture contract
Some checks failed
required-ci / gerbil-compat (pull_request) Successful in 3m57s
version-policy / required (pull_request) Successful in 5m3s
required-ci / required (pull_request) Has been cancelled
dtrace / freebsd-usdt (pull_request) Has been cancelled
freebsd-required / required (pull_request) Has been cancelled
c26df2d8b3
dtrace: fall back to the repo wrapper when no jerboa is on PATH
Some checks failed
required-ci / gerbil-compat (pull_request) Successful in 3m55s
version-policy / required (pull_request) Successful in 5m16s
required-ci / required (pull_request) Has been cancelled
freebsd-required / required (pull_request) Has been cancelled
dtrace / freebsd-usdt (pull_request) Has been cancelled
bc06e44597
dtrace: repo wrapper fallback resolves from the repo root
Some checks failed
required-ci / gerbil-compat (pull_request) Successful in 4m6s
version-policy / required (pull_request) Successful in 5m11s
required-ci / required (pull_request) Failing after 10m19s
dtrace / freebsd-usdt (pull_request) Has been cancelled
freebsd-required / required (pull_request) Has been cancelled
847269a210
dtrace: stat the bundle raw directory itself in the tools test
Some checks failed
required-ci / gerbil-compat (pull_request) Successful in 4m2s
version-policy / required (pull_request) Successful in 4m43s
required-ci / required (pull_request) Has been cancelled
dtrace / freebsd-usdt (pull_request) Has been cancelled
freebsd-required / required (pull_request) Has been cancelled
02562860a6
dtrace: clean expected bundle dirs before the tools capture test
Some checks failed
required-ci / gerbil-compat (pull_request) Successful in 4m0s
version-policy / required (pull_request) Successful in 4m29s
required-ci / required (pull_request) Has been cancelled
dtrace / freebsd-usdt (pull_request) Has been cancelled
freebsd-required / required (pull_request) Has been cancelled
694383d498
dtrace: clean root-owned bundle dirs with matching privilege
Some checks failed
required-ci / gerbil-compat (pull_request) Successful in 4m3s
version-policy / required (pull_request) Successful in 4m47s
required-ci / required (pull_request) Failing after 10m4s
dtrace / freebsd-usdt (pull_request) Has been cancelled
freebsd-required / required (pull_request) Has been cancelled
51a993efe5
dtrace: published bundles freeze raw dirs to 0555
Some checks failed
required-ci / gerbil-compat (pull_request) Successful in 4m6s
version-policy / required (pull_request) Successful in 5m0s
required-ci / required (pull_request) Failing after 9m51s
freebsd-required / required (pull_request) Successful in 12m37s
dtrace / freebsd-usdt (pull_request) Has been cancelled
1f29a05dfe
dtrace: declare the identity helper and its test as native shims
Some checks failed
required-ci / gerbil-compat (pull_request) Successful in 4m1s
version-policy / required (pull_request) Successful in 5m3s
dtrace / freebsd-usdt (pull_request) Failing after 10m26s
freebsd-required / required (pull_request) Successful in 12m44s
required-ci / required (pull_request) Successful in 14m47s
2e1d9991a4
dtrace: build the process-identity helper on demand in capture
All checks were successful
required-ci / gerbil-compat (pull_request) Successful in 4m6s
version-policy / required (pull_request) Successful in 5m5s
freebsd-required / required (pull_request) Successful in 13m12s
dtrace / freebsd-usdt (pull_request) Successful in 15m32s
required-ci / required (pull_request) Successful in 15m59s
83d9837d4d
ober force-pushed fix/issue-75-attributable-traces from 83d9837d4d
All checks were successful
required-ci / gerbil-compat (pull_request) Successful in 4m6s
version-policy / required (pull_request) Successful in 5m5s
freebsd-required / required (pull_request) Successful in 13m12s
dtrace / freebsd-usdt (pull_request) Successful in 15m32s
required-ci / required (pull_request) Successful in 15m59s
to b7f95c20f6
All checks were successful
required-ci / gerbil-compat (pull_request) Successful in 3m58s
version-policy / required (pull_request) Successful in 4m50s
dtrace / freebsd-usdt (pull_request) Successful in 14m38s
required-ci / required (pull_request) Successful in 14m49s
freebsd-required / required (pull_request) Successful in 16m19s
2026-09-22 00:44:39 -04:00
Compare
ober scheduled this pull request to auto merge when all checks succeed 2026-09-22 00:52:21 -04:00
ober merged commit 2b00a04277 into master 2026-09-22 00:52:31 -04:00
ober referenced this pull request from a commit 2026-09-22 00:52:32 -04:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ober/jerboa!90
No description provided.