Skip to content

Emit one addressing convention for every frame - #830

Merged
rkennke merged 3 commits into
mainfrom
ci/uniform-pc-offset
Sep 30, 2026
Merged

rkennke merged 3 commits into
mainfrom
ci/uniform-pc-offset

Conversation

@rkennke

@rkennke rkennke commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Closes the pc_offset question PROF-15934 left open, now that we know nothing consumes the value.

Addresses PROF-16096. Follows PROF-15934 / PROF-15955 / PROF-16059.

The problem

One trace carried two conventions, and nothing said which was which:

Path Emitted pc_offset
walkFP / walkDwarf (RA - 1) - imageBase — callchain[] holds attribution addresses since #786
walkVM RA - imageBase — lookups used the attribution address, the offset did not
walkKernel raw, straight from the kernel

#786 flagged exactly this ("offsets are not uniform within a single stack") and deferred it, because the wire value looked like a cross-team contract worth not moving. #813 then deliberately froze walkVM on raw for the same reason.

That reason is gone: no service consumes the field today. So the split is worth closing now, while it costs nothing, rather than preserving it indefinitely behind a comment.

Which convention, and why

Attribution, not raw.

callchain[] is not only the wire payload — it feeds local symbolication through convertNativeTrace as well. #786 made those entries attribution addresses precisely to fix boundary misattribution. Converging on raw would reintroduce that bug, or require carrying a parallel flag array to avoid it — option (b) from #786's own list, with its stated cost. Attribution is also already the majority convention in-tree; walkVM and walkKernel were the outliers.

Changes

  1. profiler.cpp — resolveNativeFrameForWalkVM derives pc_offset from lookup_pc, the address its lookups already used. Two lines.
  2. perfEvents_linux.cpp — walkKernel adjusts everything past the leaf. perf_callchain_user hands back the interrupted pc first and return addresses after it, so the leaf is exact and the rest are not.
  3. stackWalker.h / RemoteSymbolication.md — the convention written down as one rule, including the part a consumer needs: do not apply your own return-address adjustment.
  4. Test inverted — see below.

Two things deliberately left unadjusted

LBR entries. Not an exception to the rule: from is the branch instruction and to is its target, so both already name the instruction to symbolize. Subtracting one would step off the front.

StackContext::pc. A resume point handed to the JVM, not something anyone symbolizes. Now stated in the header so it does not read as an oversight.

About the inverted test

PcOffsetStaysDerivedFromTheRawPc asserted the old behaviour and was mutation-checked in that direction. It is inverted here rather than deleted, renamed PcOffsetUsesTheAttributionAddress, with a comment recording that the constraint was deliberate and why it was lifted — otherwise the next reader finds a reversed assertion in git log with no explanation.

I confirmed it failed before changing it (2048 vs 2047), so the behaviour change is real and the test was genuinely gating it.

Verification

  • gtestDebug and gtestRelease: 71 binaries, 0 failures each.
  • Checked that the walkKernel change actually compiled here rather than assuming: perfEvents_linux.cpp has no enclosing platform guard and its .o is produced in both configs.

Not verified locally: anything Linux-specific at runtime. walkKernel needs a live perf session, which no test exercises — the change there rests on the documented perf_callchain_user ordering plus review. CI's release and sanitizer gtests (#821) cover the build on both arches.

Follow-up worth deciding separately

The packed field still has no version bit. With no consumer that costs nothing today, but if one appears later and guesses wrong there is no way to detect it. Recording the convention in JFR metadata rather than the packed field would be the cheap insurance. Not done here.

🤖 Generated with Claude Code

A single trace carried two. walkFP and walkDwarf put attribution addresses
into callchain[], so their pc_offset came out as the address the call was made
from. walkVM derived its offset from the raw pc, and walkKernel passed the
kernel's return addresses through untouched. Nothing marked which was which,
and the packed field has no version bit to tell them apart.

PROF-15934 left this open because the wire value looked like a cross-team
contract worth not moving. It turns out nothing consumes it, so the split is
worth closing now rather than preserving indefinitely.

Attribution wins over raw because callchain[] feeds local symbolication too:
going the other way would reintroduce the boundary misattribution PROF-15934
fixed, or need a parallel flag array to avoid it.

walkVM's offset now comes from the address its lookups already used.
walkKernel adjusts everything past the leaf, the kernel having handed back the
interrupted pc first and return addresses after it. LBR entries stay as they
are, which is the same rule rather than an exception: a branch endpoint
already names the instruction to symbolize. StackContext::pc also stays exact
-- it is a resume point handed to the JVM, not something anyone symbolizes.

The contract is written down on StackWalker and in RemoteSymbolication.md,
including the part a consumer needs: do not adjust these offsets again.

PcOffsetStaysDerivedFromTheRawPc asserted the old behaviour and was
mutation-checked that way, so it is inverted here rather than deleted, with a
note saying why -- the constraint it encoded was deliberate and is now lifted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@rkennke
rkennke requested a review from a team as a code owner September 29, 2026 10:39

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6e5532c254

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread ddprof-lib/src/main/cpp/perfEvents_linux.cpp

@datadog-prod-us1-4 datadog-prod-us1-4 Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bits Code Review: FAIL

The implementation adopts attribution addresses consistently, but three authoritative comments still describe the old raw-PC behavior, contradicting the newly declared unversioned wire contract.

Open Bits AI session

🤖 Bits Code Review · Commit 6e5532c · @DataDog review to ask questions

Comment thread ddprof-lib/src/main/cpp/stackWalker.h
@dd-octo-sts

dd-octo-sts Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

CI Test Results

Run: #36706309429 | Commit: f2a4252 | Duration: 16m 25s (longest job)

✅ All 32 test jobs passed

Status Overview

JDK glibc-aarch64/debug glibc-amd64/debug musl-aarch64/debug musl-amd64/debug
8 - ✅ - -
8-ibm - ✅ - -
8-j9 ✅ ✅ - -
8-librca - - ✅ ✅
8-orcl - ✅ - -
11 - ✅ - -
11-j9 ✅ ✅ - -
11-librca - - ✅ ✅
17 ✅ ✅ - -
17-graal ✅ ✅ - -
17-j9 ✅ ✅ - -
17-librca - - ✅ ✅
21 ✅ ✅ - -
21-graal ✅ ✅ - -
21-librca - - ✅ ✅
25 ✅ ✅ - -
25-graal ✅ ✅ - -
25-librca - - ✅ ✅

Legend: ✅ passed | ❌ failed | ⚪ skipped | 🚫 cancelled

Summary: Total: 32 | Passed: 32 | Failed: 0


Updated: 2026-09-30 11:24:16 UTC

@dd-octo-sts

dd-octo-sts Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

✅ All 40 integration tests passed

📊 Dashboard · 👷 Pipeline · 📦 e19f3d08

@jbachorik

Copy link
Copy Markdown
Collaborator

LGTM!

walkVM/walkKernel now emit attribution addresses like walkFP/walkDwarf;
drop the remaining comments describing them as raw-PC producers.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@datadog-prod-us1-4

This comment has been minimized.

@rkennke
rkennke merged commit 7cf4d89 into main Sep 30, 2026
115 checks passed
@rkennke
rkennke deleted the ci/uniform-pc-offset branch September 30, 2026 11:57
@github-actions github-actions Bot added this to the 1.52.0 milestone Sep 30, 2026
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