You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Fix reference-chain discovery and leak test prerequisites - #889
Fix native reference-chain discovery and correct two test-fixture prerequisites:
Register candidates before the first heap walk can finish and release its tags. Let later allocating threads enter the bounded thread summary without inheriting an evicted thread's counts or ages.
Keep observed collections eligible for bounded revisits after reparenting. Index static-field holders discovered through another object, and JNI global roots on both first admission and rediscovery. Deduplicate overlapping FIFO selections.
Preserve class histories explicitly seeded by debug JNI test hooks across real GC folds. An explicit DEBUG-only seed method owns this bookkeeping. The new class-history field and preservation branch are compiled out of release builds; the production recorder retains its original signature without a synthetic_sample parameter. Ordinary production histories retain their normal updates and decay.
Increase the external cache fixture's inline padding from 32 to 128 longs. Preserve its one-shot allocator threads, allocation schedule, object count limit, and strict chain assertions.
Motivation:
Release validation exposed missing reference chains and incomplete holder-index registration. Native regressions reproduce the missing admission paths without depending on timing.
The remaining macOS failures also exposed fixture problems. Real GC updates could overwrite a debug test's seeded class signal. In a captured release failure, all 63 sampled CachedPayload survivors were spread across workers with at most six samples each; the detector requires eight for these one-age cohorts. Waiting cannot create the missing allocation samples. The original 272-byte payload was therefore an unreliable positive fixture at the 256KiB sampling interval. With 1,040-byte payloads in the same JVM, the captured passing run had 20 workers with at least eight samples. Padding stays on the payload itself, avoiding a competing array allocation.
Additional Notes:
No chain assertion, allocator-thread pattern, allocation-round count, GC-round count, timeout, traversal budget, detection threshold, test tag, or quarantine is relaxed. The fixture change increases retained bytes per object; the object graph and maximum object count are preserved. The small-cohort rejection tests remain in place. Thread summaries remain bounded and approximate.
How to test the change?:
Added native regressions for candidate registration order, late allocating threads, persistent collection revisits after mutation and reparenting, static/JNI-global admission paths, and seeded class-history preservation across real GC folds. Negative checks cover invented counts, non-collection eligibility, and ordinary production-history decay. The bug regressions failed before their respective fixes.
Latest full Linux validation on commit ba9328222:
Linux ARM64/glibc, Oracle GraalVM 17.0.12+8.1. The container's commit and all 822 tracked regular files matched the PR worktree before and after testing.
Full slow debug: 19 passed, no skips or failures.
Full slow release: 18 passed, one skipped, no failures.
Full regular release: 203 passed, 46 skipped, no failures.
Complete native debug and release configurations: all 82 test executables ran successfully in each configuration, with no skipped native tasks.
The complete wrapper invocation succeeded in 11m 51s, with no test filters, exclusion flags, skip-tests or skip-gtest properties:
The reported Java skip counts are retained as skips, including unmet JVM-extension and DEBUG-hook assumptions. There were no source changes or manual retries during this complete Linux run. Full logs, XML reports and source hashes are preserved locally.
Earlier validation also confirmed that the new class-history field, seed method and preservation branch are absent from release compiler output, and that ordinary-history decay remains covered in debug and release. Formatting and git diff --check passed.
Intermittency remains a limitation: an earlier full Linux slow-release run failed the thread-created-after-recording-start correlation case; this fresh full run did not reproduce it. Earlier macOS full runs also had missing-chain failures followed by passing focused reruns. The debug-only refactor does not establish that every intermittent failure is fixed. At the user's request, macOS is outside the latest release validation.
For Datadog employees:
This PR doesn't touch code that signs or publishes builds or packages, or handles credentials.
kaahos
changed the title
Fix reference-chain discovery for changing caches and later allocating threads
Fix reference-chain discovery and leak test prerequisites
Oct 23, 2026
Cross-reference for follow-up findings from validating this branch's regime (PROF-16305 work):
1. Fixed elsewhere — pre-existing cache invalidation defect (PROF-16316, #898).
Validation of this branch's load regime exposed a pre-existing product bug: improveChain()'s deferred invalidation erases resolved leak-correlated chains that the restartSearch() keep-across-restart contract says must survive; if the improve fires in a terminal pass, the chains cannot be rebuilt (candidate/discovered state zeroed, search pain-budget-blocked ~11-15 s) and the correlation is lost for the whole window. This is what produced residual [tl-correlation-not-found] failures of ThreadLocalLeakReferenceChainTest.shouldCorrelateLeakOnThreadCreatedAfterRecordingStart on JDK 11 (~2/10 at default level; deterministic when instrumented — pass/fail splits on the pass-1 CPU pain-budget debt left at the canary close). RCA + fix (EVICT/REBUILD split, gtest fails-before/passes-after): #898. The involved paths are untouched by this PR — it is pre-existing, merely exposed more often by this PR's changed tag-map load.
2. Open observation — cache-leak residual on JDK 11 attributable to this branch.
Control experiment on a quiet Linux x64 box, 10 iterations each, ReferenceChainTrackingTest.shouldReconstructReferrerChainThroughUnboundedCacheLeak on JDK 11.0.32-tem (debug, level off, -Ptests=com.datadoghq.profiler.referencechains.*): baseline f9511ecd7 (parent of this PR) 0/10 failures vs this PR's commit 7e267003b2/10 failures with the known "Never observed a …CachedPayload…" assertion. On 21.0.3-tem (the CI test JDK) this PR reduced the rate 0.80 → ~0.11-0.30, so this is not blocking CI — but the JDK 11 regression appears to come from this PR's revisit/admission changes rather than the test-side work stacked on top (identical 2/10 with the stacked test changes present, 8/10+1/10 with them absent across two arms). Worth a look when this PR is reviewed; happy to provide the full artifacts (control-arm logs/XMLs) if useful.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
test:asanRun CI tests with AddressSanitizer configurationtest:fuzztest:tsanRun CI tests with ThreadSanitizer configuration
2 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?:
Fix native reference-chain discovery and correct two test-fixture prerequisites:
Motivation:
Release validation exposed missing reference chains and incomplete holder-index registration. Native regressions reproduce the missing admission paths without depending on timing.
The remaining macOS failures also exposed fixture problems. Real GC updates could overwrite a debug test's seeded class signal. In a captured release failure, all 63 sampled CachedPayload survivors were spread across workers with at most six samples each; the detector requires eight for these one-age cohorts. Waiting cannot create the missing allocation samples. The original 272-byte payload was therefore an unreliable positive fixture at the 256KiB sampling interval. With 1,040-byte payloads in the same JVM, the captured passing run had 20 workers with at least eight samples. Padding stays on the payload itself, avoiding a competing array allocation.
Additional Notes:
No chain assertion, allocator-thread pattern, allocation-round count, GC-round count, timeout, traversal budget, detection threshold, test tag, or quarantine is relaxed. The fixture change increases retained bytes per object; the object graph and maximum object count are preserved. The small-cohort rejection tests remain in place. Thread summaries remain bounded and approximate.
How to test the change?:
Added native regressions for candidate registration order, late allocating threads, persistent collection revisits after mutation and reparenting, static/JNI-global admission paths, and seeded class-history preservation across real GC folds. Negative checks cover invented counts, non-collection eligibility, and ordinary production-history decay. The bug regressions failed before their respective fixes.
Latest full Linux validation on commit
ba9328222:The reported Java skip counts are retained as skips, including unmet JVM-extension and DEBUG-hook assumptions. There were no source changes or manual retries during this complete Linux run. Full logs, XML reports and source hashes are preserved locally.
Earlier validation also confirmed that the new class-history field, seed method and preservation branch are absent from release compiler output, and that ordinary-history decay remains covered in debug and release. Formatting and git diff --check passed.
Intermittency remains a limitation: an earlier full Linux slow-release run failed the thread-created-after-recording-start correlation case; this fresh full run did not reproduce it. Earlier macOS full runs also had missing-chain failures followed by passing focused reruns. The debug-only refactor does not establish that every intermittent failure is fixed. At the user's request, macOS is outside the latest release validation.
For Datadog employees: