Avoid retaining invalid VM method pointers - #699
Conversation
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e61602b3c6
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Jira: PROF-15568 |
CI Test ResultsRun: #30559202741 | Commit:
Status Overview
Legend: ✅ passed | ❌ failed | ⚪ skipped | 🚫 cancelled Summary: Total: 32 | Passed: 32 | Failed: 0 Updated: 2026-07-30 16:16:23 UTC |
Benchmark Results (commit 323b1be)Pipeline: https://gitlab.ddbuild.io/DataDog/apm-reliability/benchmarking-platform/-/pipelines/128028156 Commit:
|
| Benchmark | JDK | Latest | Dev | Δ (dev vs latest) | Issues L/D |
|---|---|---|---|---|---|
| akka-uct | 21 | ✅ 10203 ms (21 iters) | ✅ 10329 ms (21 iters) | ≈ +1.2% (±11.3%) | — / — |
| akka-uct | 25 | ✅ 8828 ms (24 iters) | ✅ 8885 ms (24 iters) | ≈ +0.6% (±10.1%) | — / — |
| finagle-chirper | 21 | ✅ 6000 ms (33 iters) | ✅ 5941 ms (33 iters) | ≈ -1% (±24.5%) | |
| finagle-chirper | 25 | ✅ 5431 ms (36 iters) | ✅ 5450 ms (36 iters) | ≈ +0.3% (±24.1%) | |
| fj-kmeans | 21 | ✅ 2760 ms (68 iters) | ✅ 2634 ms (72 iters) | 🟢 -4.6% | — / — |
| fj-kmeans | 25 | ✅ 2775 ms (68 iters) | ✅ 2868 ms (66 iters) | 🔴 +3.4% | — / — |
| future-genetic | 21 | ✅ 2062 ms (90 iters) | ✅ 2097 ms (88 iters) | ≈ +1.7% (±2.7%) | — / — |
| future-genetic | 25 | ✅ 2080 ms (89 iters) | ✅ 2078 ms (89 iters) | ≈ -0.1% (±2.7%) | — / — |
| naive-bayes | 21 | ✅ 1298 ms (132 iters) | ✅ 1267 ms (135 iters) | ≈ -2.4% (±32.3%) | — / — |
| naive-bayes | 25 | ✅ 1008 ms (170 iters) | ✅ 1029 ms (166 iters) | ≈ +2.1% (±32%) | — / — |
| reactors | 21 | ✅ 16262 ms (15 iters) | ✅ 16509 ms (15 iters) | ≈ +1.5% (±9.1%) | — / — |
| reactors | 25 | ✅ 18524 ms (15 iters) | ✅ 18087 ms (15 iters) | ≈ -2.4% (±6%) | — / — |
Internal counter details (ddprof)
ddprof internal counters, latest / dev (✅ = 0, · = unavailable):
| Benchmark | JDK | Dropped rec | Dropped jvmti | Dropped trace | Skipped WC | AGCT fail | Unwind fail |
|---|---|---|---|---|---|---|---|
| akka-uct | 21 | ✅ / ✅ | ✅ / ✅ | 3 / 3 | 1878 / 1894 | ✅ / ✅ | ✅ / ✅ |
| akka-uct | 25 | ✅ / ✅ | ✅ / ✅ | 4 / 5 | 2349 / 2241 | ✅ / ✅ | ✅ / ✅ |
| finagle-chirper | 21 | ✅ / ✅ | ✅ / ✅ | 2 / 4 | 8924 / 8610 | ✅ / ✅ | ✅ / ✅ |
| finagle-chirper | 25 | ✅ / ✅ | ✅ / ✅ | 1 / 2 | 8312 / 8222 | ✅ / ✅ | ✅ / ✅ |
| fj-kmeans | 21 | ✅ / ✅ | ✅ / ✅ | 1 / 1 | 1297 / 1293 | ✅ / ✅ | ✅ / ✅ |
| fj-kmeans | 25 | ✅ / ✅ | ✅ / ✅ | 1 / 1 | 1308 / 1298 | ✅ / ✅ | ✅ / ✅ |
| future-genetic | 21 | ✅ / ✅ | ✅ / ✅ | 3 / ✅ | 2944 / 2982 | ✅ / ✅ | ✅ / ✅ |
| future-genetic | 25 | ✅ / ✅ | ✅ / ✅ | 1 / 2 | 2902 / 2802 | ✅ / ✅ | ✅ / ✅ |
| naive-bayes | 21 | ✅ / ✅ | ✅ / ✅ | 4 / 4 | 3510 / 3516 | ✅ / ✅ | ✅ / ✅ |
| naive-bayes | 25 | ✅ / ✅ | ✅ / ✅ | 2 / 4 | 3492 / 3494 | ✅ / ✅ | ✅ / ✅ |
| reactors | 21 | ✅ / ✅ | ✅ / ✅ | 1 / 1 | 1516 / 1596 | ✅ / ✅ | ✅ / ✅ |
| reactors | 25 | ✅ / ✅ | ✅ / ✅ | ✅ / ✅ | 1884 / 1865 | ✅ / ✅ | ✅ / ✅ |
This comment has been minimized.
This comment has been minimized.
kaahos
left a comment
There was a problem hiding this comment.
It looks good to me, Thanks for the fix!
What does this PR do?:
Avoid retaining a raw
VMMethod*after HotSpot stack walking has already returnedJMETHODID_NOT_WALKABLE.Motivation:
JMETHODID_NOT_WALKABLEmeans the walker could not establish that theVMMethod*is safe to use as a jmethodID source. Previously, the five-argumentfillFrameconverted that rejection into a raw-pointerframe, allowing the pointer to survive in
CallTraceStorageuntil a later dump.Additional Notes:
At dump time,
HotspotSupport::resolvecould dereference the retainedVMMethod*and synthesize a jmethodID from metadata HotSpot had already torn down or reused.Lookup::fillJavaMethodInfocould then issueJVMTI calls on that stale or garbage identity. This is a strong match for the observed
jvmti_GetClassSignaturecrash on releases where the known upstream two-call class-unload race is fixed.The fix keeps
JMETHODID_NOT_WALKABLEin the captured frame and normalizes it to the sharedunknownmethod before any JVMTI call. The intentionalnullptrraw-pointer fallback is unchanged.How to test the change?:
./.claude/commands/build-and-summarize spotlessApply:ddprof-lib:gtestDebug_hotspotMethodId_ut:ddprof-test:testDebug -Pskip-gtest -Ptests=JavaProfilerTest.rawMethodResolutionDuringRetransformationStressThe focused native test forces the rejected sentinel, verifies that it is not packed as a raw pointer, and verifies deferred lookup resolves it as the shared unknown method without reaching JVMTI.
For Datadog employees: