From f681cf63796f16686bdb011a6d6b675cabeb718a Mon Sep 17 00:00:00 2001 From: Necco Ceresani Date: Wed, 19 Aug 2026 15:35:27 -0400 Subject: [PATCH] README: lead with yeet run gh:yeet-src/hotspot The one-liner is the intended entrypoint: yeet's source pipeline clones the repo, runs make against its own cache and starts the script, with the BPF toolchain fetched automatically. yeet-src is a trusted origin, so the auto-build runs without a consent prompt. Keep the clone-and-build recipe for people changing the script, and add a FAQ entry for the clone-auth failure, since gh: tries SSH before falling back to HTTPS. --- README.md | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8f11749..782beab 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ The thing you would otherwise reach for is `perf record` followed by `perf repor ## Questions this tool answers **One process is pinning a core and I need to know which function, right now.** -`yeet run . --tty`, click the process, and read the top of the table. Rows are self-time only, sorted hottest first, so the top row is where the CPU actually is rather than a caller that merely contains it. The first rows land in about a second at the default 499 Hz. See [What you're looking at](#what-youre-looking-at). +`yeet run gh:yeet-src/hotspot --tty`, click the process, and read the top of the table. Rows are self-time only, sorted hottest first, so the top row is where the CPU actually is rather than a caller that merely contains it. The first rows land in about a second at the default 499 Hz. See [What you're looking at](#what-youre-looking-at). **I'm SSHed into a box where I can't install `perf` and there's no matching `linux-tools` package. Can I still profile?** Yes, and this is the case the shape is for. `perf` needs a `linux-tools` build matched to the running kernel, which is exactly what a minimal or slightly-behind image doesn't have. `hotspot` needs the yeet daemon and this script; the sampler is a CO-RE BPF program, so there's no per-kernel recompile and nothing to match. It draws in the terminal you're already in, so there's also no port to forward. @@ -72,11 +72,23 @@ Not directly. `hotspot` is a mouse-driven TUI with no headless mode and no `--js ## Quick start ```sh -curl -fsSL https://yeet.cx | sh +curl -fsSL https://yeet.cx | sh # install yeet, once +yeet run gh:yeet-src/hotspot --tty # clone, build and run in one step +``` +[Manual install guide](https://yeet.cx/docs/install/manual-installation?utm_source=github&utm_medium=readme&utm_campaign=hotspot) | Linux only + +That is the whole install. `yeet run` clones the repo into its own cache, runs `make` to +compile `bin/probe.bpf.o` and bundle the JS, then starts the script; the BPF toolchain is +fetched automatically, so there is no clang, bpftool or `linux-tools` to install first. +`yeet-src` is a trusted source for the runtime, so the build runs without a consent prompt. + +Working on the script itself instead of just running it? Clone it and build in place: + +```sh +git clone https://github.com/yeet-src/hotspot && cd hotspot make # compile bin/probe.bpf.o + bundle the JS (toolchain auto-fetched) yeet run . --tty # the live process table; click a process to profile it ``` -[Manual install guide](https://yeet.cx/docs/install/manual-installation?utm_source=github&utm_medium=readme&utm_campaign=hotspot) | Linux only With no flags you land on the process table: every process with an executable, sorted by name. Kernel threads are filtered out because they have no `exe` and no user stacks. Click a row to select it, click the selected row (or `⏎`) to start profiling, and the pane becomes a live profile. No sampling happens until you open a process. @@ -90,11 +102,14 @@ Script flags go **after `--`** so the runtime routes them to the script rather t | `--strip=` | none | strip a build-machine path prefix from DWARF paths to make them repo-relative | ```sh -yeet run . --tty -- --freq 997 # sample harder -yeet run . --tty -- --repo torvalds/linux --rev v6.12 # link kernel rows to a tag -yeet run . --tty -- --repo me/svc --strip /build/src/ # bridge a container build path +R=gh:yeet-src/hotspot +yeet run $R --tty -- --freq 997 # sample harder +yeet run $R --tty -- --repo torvalds/linux --rev v6.12 # link kernel rows to a tag +yeet run $R --tty -- --repo me/svc --strip /build/src/ # bridge a container build path ``` +(From a clone, `.` replaces `gh:yeet-src/hotspot` in any of these.) + Runs until `q` or `Ctrl-C`. Resize the terminal and every view reflows. It needs a real terminal and mouse reporting, so don't pipe or redirect it. ## Have an agent set it up @@ -302,6 +317,9 @@ The trade is honest: sampling is statistical and cannot tell you a function was ## Building from source +You only need this section if you're changing the script. `yeet run gh:yeet-src/hotspot` runs +`make` for you against its own cached clone. + ```sh make # build bin/probe.bpf.o (clang + bpftool) + bundle the JS (esbuild) make bpf # just the BPF object @@ -370,6 +388,12 @@ There's no capture script; [`demo/README.md`](demo/README.md) has the recording ## FAQ +**`yeet run gh:yeet-src/hotspot` fails with `could not read Username for 'https://github.com'`.** +That is a clone-authentication failure, not a script problem. `gh:` shorthand tries SSH first +(`git@github.com:yeet-src/hotspot`) so private repos work with your own keys, then retries over +HTTPS. If neither has a usable credential you get this. Check `ssh -T git@github.com` succeeds, +or clone it yourself and run `yeet run . --tty` from the directory. + **Why is the top row `??` with a spinner that never resolves?** A spinner means queued, and a spinner that persists means the batch failed rather than that it's slow. The status line shows `sym: ` when symbolization errored; the most common cause is the process exiting while being profiled, since the resolver reads its live maps. Reopen the process.