8000 Add async-profiler 4.5 (from source) by bryan-minimal · Pull Request #900 · gominimal/pkgs · GitHub
[go: up one dir, main page]

Skip to content

Add async-profiler 4.5 (from source) - #900

Merged
bryan-minimal merged 4 commits into
mainfrom
add-async-profiler
Oct 23, 2026
Merged

bryan-minimal merged 4 commits into
mainfrom
add-async-profiler

Conversation

@bryan-minimal
@bryan-minimal bryan-minimal commented Oct 16, 2026 •
Copy link
Copy Markdown
Member

What

Adds packages/async-profiler (v4.5, Apache-2.0), the low-overhead sampling CPU / allocation / lock profiler for the JVM. It is item "async-profiler" in the Java loadout checklist in #899.

Built from source, not from the per-arch release tarballs:

  • libasyncProfiler.so and asprof come from upstream's Makefile (targets build/lib/libasyncProfiler.so build/bin/asprof). Upstream's all target downloads nothing; only the test targets fetch jars, and they are not run.
  • The helper classes that the agent embeds with .incbin (src/helper/one/profiler/*.class) are committed prebuilt in upstream's tree. build.sh deletes them and recompiles them from the .java next to them, using upstream's own %.class rule (-source 8 -target 8 -g:none).
  • async-profiler.jar (Java API) and jfr-converter.jar are compiled with javac --release 8, as upstream does. They are written with the DeterministicJar helper from packages/tlaplus (sorted entries, one fixed timestamp), because jar cfm / cfe stamps build time on every entry.
  • jfrconv is upstream's /bin/sh launcher with the converter jar appended, assembled the same way the Makefile does it.

Layout

Path Output
usr/bin/asprof OutputBin. It finds the agent at ../lib/libasyncProfiler.so, so /usr/bin + /usr/lib keeps upstream's bin/ + lib/ relationship.
usr/bin/jfrconv OutputBin (shell script plus the embedded jar)
usr/lib/libasyncProfiler.so OutputLib
usr/include/asprof.h OutputData
usr/share/async-profiler/{async-profiler,jfr-converter}.jar OutputData

runtime_deps: glibc, plus bash for the jfrconv launcher and jdk. There is no libstdc++ or libgcc dependency, because upstream links both statically into the .so (-static-libstdc++ -static-libgcc). asprof is linked with the gcc driver and pulls in no C++ runtime.

Reproducibility

  • C/C++: -ffile-prefix-map=$(pwd)=/builddir -gno-record-gcc-switches -Wl,--build-id=none. These go through CFLAGS_EXTRA / CXXFLAGS_EXTRA, because the Makefile's recipes ignore LDFLAGS.
  • asprof --version and jattach print __DATE__, and jfrconv --version gets a build date instead of $(shell date). All of them come from the sandbox's SOURCE_DATE_EPOCH, so they're deterministic without the package setting one.
  • As in upstream's release, strip -g is applied to the .so.

Tests

None of the tests need perf privileges. Every profiling run uses event=itimer (setitimer + SIGPROF), because the default event=cpu needs perf_events, which sandboxes usually forbid.

  • smoke: asprof --version and jfrconv --version both report 4.5.
  • agent: compiles a busy-loop program, runs it with -agentpath:/usr/lib/libasyncProfiler.so=start,event=itimer,file=out.collapsed, and requires Busy.burnCpu in the stacks. It repeats the run with .jfr output, then requires jfrconv to produce collapsed stacks containing the same frame and an HTML flame graph.
  • attach: asprof -e itimer -d 2 attaches to an already-running JVM through HotSpot dynamic attach (no ptrace) and must see Spin.spinLoop.

Notes for review

Refs #899

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added async-profiler 4.5, providing the asprof and jfrconv command-line tools, a native profiling agent, and Java profiling libraries.
    • Added support for capturing profiles from Java applications and converting profiling data to JFR format.

Low-overhead sampling CPU/alloc/lock profiler for the JVM. Builds the
native agent and asprof with upstream's Makefile, rebuilds the embedded
helper classes from source, and writes the API / converter jars with
DeterministicJar (sorted entries, fixed timestamp). Tests use
event=itimer so they need no perf_events privileges.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bryan-minimal
bryan-minimal requested a review from a team as a code owner October 16, 2026 20:27
@bryan-minimal
Copy link
Copy Markdown
Member Author

/build

@coderabbitai
coderabbitai Bot commented Oct 16, 2026 •
Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: gominimal/pkgs/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 1e9c3abe-4ddd-4b5f-92b4-ac44bb729e49
📥 Commits

Reviewing files that changed from the base of the PR and between 0618acc and 2b2fc5d.

📒 Files selected for processing: 3
  • packages/async-profiler/DeterministicJar.java
  • packages/async-profiler/build.ncl
  • packages/async-profiler/build.sh

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour.

📝 Walkthrough

Adds an async-profiler 4.5 package. The build compiles its native and Java components, creates deterministic JARs, installs the tools and supporting files, and adds smoke, agent, and attach tests.

Changes: async-profiler package

Layer / File(s) Summary
Deterministic JAR creation
packages/async-profiler/DeterministicJar.java
Adds a utility that sorts JAR entries, writes the manifest and META-INF/ first, and sets a fixed timestamp on each entry.
Package build and installation
packages/async-profiler/build.ncl, packages/async-profiler/build.sh
Defines the async-profiler 4.5 package, its dependencies and outputs. The build script compiles the native and Java components, creates the API and converter JARs with DeterministicJar, and installs the outputs.
Profiler and converter tests
packages/async-profiler/build.ncl
Adds version checks, an agent profiling test with JFR conversion checks, and an attach test against a running JVM.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant BuildSpec as build.ncl
  participant BuildScript as build.sh
  participant DeterministicJar
  participant asprof
  participant jfrconv
  BuildSpec->>BuildScript: Run the package build
  BuildScript->>DeterministicJar: Create API and converter JARs
  DeterministicJar-->>BuildScript: Write sorted JAR entries with fixed timestamps
  BuildScript-->>BuildSpec: Install package outputs
  BuildSpec->>asprof: Run version, agent, and attach tests
  BuildSpec->>jfrconv: Run version and JFR conversion tests
Loading

Suggested reviewers: norrietaylor

Merge Risk: ⚪ Minimal · up to 2b2fc

No identified issue prevents merging after the normal build and test checks.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 2 files. (1 skipped: 1 … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: adding async-profiler version 4.5 from source.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 2 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@norrietaylor norrietaylor left a comment
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The source build is solid: it recompiles the prebuilt .class files, libstdc++ is statically linked so glibc alone is right, the globs match, and the itimer tests are good. Changes needed:

  1. build.sh:13 re-exports SOURCE_DATE_EPOCH=1784505600. AGENTS.md says the sandbox sets it and the pattern is to override the consumer instead (see packages/nspr/build.sh); no other package sets it non-zero. It isn't needed: with the sandbox's 0, __DATE__ and the jfrconv date at line 73 are already deterministic. Drop it, or scope it to the sed at line 73. (minimal-check only catches =0; the policy still applies.)
  2. Rebase needed. The branch predates #897, which made jdk point at Temurin 25. CI built and tested against 21 but it will ship on 25. Please rebase and re-run /build. The PR body's "Temurin 21's javac" also needs updating. --release 8 still works on 25, but the rebuild should show it.
  3. Nit: DeterministicJar.java:5 is an identical copy from packages/tlaplus, and its comment still explains TLA+'s need for directory entries. Please make the comment generic.

Generated by Claude Code

bryan-minimal and others added 2 commits October 21, 2026 18:55
Review fixes: drop the hardcoded SOURCE_DATE_EPOCH (the sandbox already
sets one, so __DATE__ and jfrconv's build date stay deterministic), and
make the DeterministicJar.java header describe the general case instead
of tlaplus's lookup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bryan-minimal
Copy link
Copy Markdown
Member Author

Thanks @norrietaylor. All three are addressed in 2b2fc5d (on top of a merge of main, c4db3f8):

  1. SOURCE_DATE_EPOCH: dropped. __DATE__ and the jfrconv date (date -u -d "@$SOURCE_DATE_EPOCH") now come from the sandbox's value, and the comments say so.
  2. jdk: current LTS (meta over jdk-25); add jdk-25 (Temurin 25) and jdk-21 (Temurin 21) #897 / Temurin 25: I merged main instead of rebasing, so the branch didn't need a force-push. jdk now resolves to jdk-25. The branch is in this repo, so the build bot rebuilds it on its own, and that build is the run on 25. The PR body now says Temurin 25's javac.
  3. DeterministicJar.java: the header is generic now (no TLA+ specifics), with a note to keep it in step with packages/tlaplus/DeterministicJar.java.

bash -n and nickel format --check are clean, and mip dump --packages evaluates.

🤖 Generated with Claude Code

@norrietaylor norrietaylor left a comment
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All three points are addressed:

  • The SOURCE_DATE_EPOCH override is gone; it's only read at build.sh:74, under set -u.
  • #897 is merged in, so jdk resolves to jdk-25, and the PR body is updated.
  • The DeterministicJar header is generic.

One thing before merge: the minimal build on 2b2fc5d took 52s, the same as the original JDK 21 run, and it has no output. So GitHub doesn't show whether the package and its tests really rebuilt on Temurin 25. Please confirm on minimal.dev or post /build.

Nit: DeterministicJar.java:9 says to keep the two copies in step, but packages/tlaplus/DeterministicJar.java doesn't point back.


Generated by Claude Code

@bryan-minimal
Copy link
Copy Markdown
Member Author

@norrietaylor, here's the confirmation that #900 rebuilt on Temurin 25, from the build bot's own records. Our branch can't take /build, since that's fork-only, so I pulled these from build-bot telemetry (Cloud Logging, minimal-prod-builds journal).

The run for 2b2fc5d (run 405a3e28, 51.9s end to end):

  • Both res-servers logged Building package: async-profiler at 01:57:05. build.completed came at 16.3s on amd64 and 18.8s on arm64.
  • The bot then uploaded 2 new artifacts, with 0 already present, so nothing came from the cache.
  • It signed provenance for both arches and ran the 30 package checks in sandboxes, with 0 failures.
  • The 52s is real build time, not a cache hit. async-profiler is small: one C++ shared library plus a few javac'd helpers.

The JDK changed between the two heads, so the input closure is new:

head jdk meta resolves to amd64 spec arm64 spec resolved deps
a379a88 (10-16) Temurin 21 (let version = "21.0.12.1", temurin21-binaries) b1593322… ed5eb40c… 15
2b2fc5d (10-22) jdk-25 (import "../jdk-25/build.ncl", #897) 16f2d9a3… b30de013… 16

The signed spec hashes match mip dump at each head, and the artifact digests changed too: amd64 ff88520b… became d0185bec…, arm64 0a797258… became 9f534331….

On the DeterministicJar nit: agreed. I'll add the pointer back in packages/tlaplus/DeterministicJar.java as a follow-up once this merges. DeterministicJar.java is a hashed Local input, so even a comment-only edit rebuilds tlaplus, and I'd rather not fold that into this PR.

🤖 Generated with Claude Code

@bryan-minimal
bryan-minimal added this pull request to the merge queue Oct 22, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks Oct 23, 2026
@bryan-minimal
bryan-minimal added this pull request to the merge queue Oct 23, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks Oct 23, 2026
@bryan-minimal
bryan-minimal added this pull request to the merge queue Oct 23, 2026
Merged via the queue into main with commit 4017ba5 Oct 23, 2026
10 checks passed
@bryan-minimal
bryan-minimal deleted the add-async-profiler branch October 23, 2026 03:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0