Skip to content

[3.0] Three merged fixes silently reverted by release-prep commit f298251e #920

Description

@jbachorik

Summary

The release-prep commit f298251e ("chore(release): 3.0.0 prep — Java<17 deprecation warning, docs/impl sync", 2026-07-11) was authored against a stale checkout and silently reverted merged fixes from at least three separate PRs. Three of those reverts are still live on develop.

The commit message documents none of the reverts — every one of them looks like an unintended overwrite. Its own message hints at the mechanism: "workflow stash-pop conflicts resolved keeping upstream action versions".

Found while reviewing #905, which is re-fixing one of these regressions without anyone realising it was a regression.

Regressions still present on develop

1. Remote clients share SharedSettings.GLOBAL again — HIGH

ef953ac0 gave each remote client its own settings copy. f298251e reverted it along with the comment explaining why:

Give each remote client its own settings copy, seeded from the agent baseline. Using the shared GLOBAL instance here let one client's SET_PARAMS (debug, dumpDir, outputFile, and notably trusted) leak into every other client and into the global transformer. The premain/local path already isolates settings the same way.

Current state — the asymmetry the fix removed is back:

  • btrace-agent/.../Main.java:1475 (local/premain) — new ClientContext(inst, transformer, argMap, clientSettings) — isolated copy
  • btrace-agent/.../Main.java:1514 (remote accept loop) — new ClientContext(inst, transformer, argMap, settings)the shared global

settings there is the static field Main.java:180: private static final SharedSettings settings = SharedSettings.GLOBAL; — the same instance handed to BTraceTransformer via DebugSupport at Main.java:119.

Why this is worse than a tidiness issue:

  • RemoteClient.getClient (RemoteClient.java:151,163) does SharedSettings settings = ctx.getSettings(); then settings.from(((SetSettingsCommand) cmd).getParams()) on SET_PARAMS — mutating the context's instance in place, i.e. the global.
  • SharedSettings.from(Map) treats trusted as non-downgrading (SharedSettings.java:82,86: trusted |= b). So a single client that sets trusted flips it on for the agent globally, for every concurrent and subsequent client, permanently — there is no path back to false.
  • from() also copies grantedPermissions, deniedPermissions and grantAll.
  • Authentication is only enforced in prepared mode (ControlServer.isAuthenticationRequired() returns credentials != null, and credentials are created only when preparedMode is set), so on a normal attach the control port has no auth in front of this.

2. QUEUE_PROCESSOR_STACK_SIZE removed — JDK 26+ risk

Added by #843 (9f39a250, earlier 1317782c), removed by f298251e, never restored. The dropped code and its rationale:

ClassFile API's StackMapGenerator can exhaust the default stack depth when processing complex methods in JDK 26+ (class-file major >= 70). Use 4 MB on those JVMs only; on older JVMs keep the default (0 = JVM-chosen) to avoid any OS-level stack-allocation overhead that was intermittently delaying test startup on JDK 8/11/21 CI machines.

Main.java:191 is back to new Thread(r, "BTrace Command Queue Processor") with no explicit stack size, and QUEUE_PROCESSOR_STACK_SIZE has zero references. The CI matrix includes 27.ea.31-open.

3. ASM downgraded 9.10.1 → 9.9.1 in the Gradle plugin

btrace-gradle-plugin/build.gradle:30-31 — Renovate bumped ASM to 9.10.1 in #839 (aaed26ff); f298251e put it back to 9.9.1. Still 9.9.1 today, and the open Renovate PR #854 does not cover it, so it will not self-heal. This is the only ASM coordinate outside the version catalog, which is likely why nothing caught it.

(The same hunk also reverted junit-jupiter 6.1.1 → 5.11.4, but that has since moved to 5.14.4 independently and #902 settled the v6 question deliberately — not actionable.)

Already handled — do not double-fix

Audit scope and method

For all 50 files in f298251e, extracted every removed line and checked whether it is still absent from develop, then attributed each surviving removal with git log -S.

Reviewed and cleared as intentional (all stated in the commit message):

  • .github/workflows/* — these went floating-tag → pinned SHA digest. A hardening improvement, not a revert.
  • release.ymlio.btrace:btrace-client/-agent/-boot → the actually-published io.btrace:btrace.
  • btrace-dist/build.gradle, btrace-gradle-plugin/build.gradle POM blocks, docker/* — GPLv2+CE → Apache-2.0 relicensing.
  • messages.properties — removal of the unimplemented --grant/--deny/--grantAll client flags.
  • samples/AllMethods.java, ~30 docs files — org.openjdk.btraceio.btrace rename, Java support policy, 3.0 version references.

Only btrace-agent/.../Main.java, btrace-client/.../Client.java and btrace-gradle-plugin/build.gradle carry unintended reverts.

Work

  • Restore per-client SharedSettings isolation in the remote accept loop (Main.java:1514), matching the local path at :1475.
  • Add a regression test: two remote clients, one sends SET_PARAMS{trusted=true}, assert the other client's context and SharedSettings.GLOBAL are unaffected. This is the test whose absence let the revert through twice.
  • Restore QUEUE_PROCESSOR_STACK_SIZE and its resolveQueueProcessorStackSize() helper.
  • Re-bump ASM to 9.10.1 in btrace-gradle-plugin/build.gradle, and consider moving the coordinate into the version catalog so Renovate tracks it with everything else.
  • Merge client: fix JAVA_HOME NPE at startup and malformed cmdQueueLimit token #905 for the cmdQueueLimit line.

Prevention

Three merged fixes were reverted by one commit and nobody noticed for two weeks. Worth considering before 3.0.0:

  • None of the reverted fixes had a test that would have failed. The settings-isolation one in particular is cheap to test and high-value.
  • Large mixed-content commits (8 source files + ~42 docs/workflow files, 2084/379 lines) make review of the source portion effectively impossible. Splitting docs sync from behavioural change would have surfaced all three.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions