Skip to content

Fix memory leak in JfrMetadata::reset() - #694

Draft
jbachorik wants to merge 1 commit into
mainfrom
fix/jfrmetadata-reset-leak
Draft

Fix memory leak in JfrMetadata::reset()#694
jbachorik wants to merge 1 commit into
mainfrom
fix/jfrmetadata-reset-leak

Conversation

@jbachorik

@jbachorik jbachorik commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?:
JfrMetadata::reset() cleared _root._children/_root._attributes without deleting the heap-allocated Element/NoField objects initialize() had allocated, leaking them and leaving the tree vulnerable to use-after-free if the allocator later reused a freed address. Adds recursive deletion of the Element tree and the tracked _nofields list before clearing.

Motivation:
Only reachable via a profiler restart (reset() followed by initialize() a second time in the same process). Found while investigating PROF-15075 (SIGSEGV in Recording::writeElement) but not its cause — that crash trace shows a plain chunk dump with no restart involved. Closing this separately since it's a real leak/UAF risk on its own.

How to test the change?:

  • ddprof-lib/src/test/cpp/jfrMetadata_ut.cpp exercises initialize()/reset() cycles, including with context attributes, and asserts no leaked/dangling Elements.

For Datadog employees:

  • If this PR touches code that signs or publishes builds or packages, or handles
    credentials of any kind, I've requested a security review (run the dd:platform-security-review
    skill, or file a request via the PSEC review form).
    bewaire also runs automatically on every PR.
  • This PR doesn't touch any of that.
  • JIRA: [JIRA-XXXX]

Unsure? Have a question? Request a review!

reset() cleared _root._children/_attributes without deleting the
heap-allocated Element/NoField objects initialize() had allocated.
Only reachable via a Profiler restart (reset() -> initialize() a
second time in the same process); unrelated to PROF-15075, which
crashes on a plain chunk dump with no restart involved (split out
of #692 per https://datadoghq.atlassian.net/browse/PROF-15075).
Copilot AI review requested due to automatic review settings July 28, 2026 11:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@jbachorik jbachorik added the AI label Jul 28, 2026
@jbachorik jbachorik changed the title Fix memory leak in JfrMetadata::reset() (split from PROF-15075) Fix memory leak in JfrMetadata::reset() Jul 28, 2026
@dd-octo-sts

dd-octo-sts Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

CI Test Results

Run: #30355775898 | Commit: ca6c687 | Duration: 17m 59s (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-07-28 12:14:17 UTC

@dd-octo-sts

dd-octo-sts Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Benchmark Results (commit 008d688)

Pipeline: https://gitlab.ddbuild.io/DataDog/apm-reliability/benchmarking-platform/-/pipelines/127401287 Commit: 008d6889e4f9acc4be699bb2ac845f3396e20528

⚠️ Significant outliers

  • 🟢 fj-kmeans (JDK 21): runtime -3.9% (2745→2638 ms)
  • 🟢 future-genetic (JDK 21): runtime -3% (2122→2058 ms)
Runtime details (per benchmark × JDK)
Benchmark JDK Latest Dev Δ (dev vs latest) Issues L/D
akka-uct 21 ✅ 10193 ms (21 iters) ✅ 10416 ms (21 iters) ≈ +2.2% (±11.2%) — / —
akka-uct 25 ✅ 8880 ms (24 iters) ✅ 8743 ms (24 iters) ≈ -1.5% (±10%) — / —
finagle-chirper 21 ✅ 6002 ms (33 iters) ✅ 5929 ms (33 iters) ≈ -1.2% (±24.7%) ⚠️ W:3 / ⚠️ W:3
finagle-chirper 25 ✅ 5437 ms (36 iters) ✅ 5445 ms (36 iters) ≈ +0.1% (±24.3%) ⚠️ W:3 / ⚠️ W:3
fj-kmeans 21 ✅ 2745 ms (68 iters) ✅ 2638 ms (72 iters) 🟢 -3.9% — / —
fj-kmeans 25 ✅ 2832 ms (66 iters) ✅ 2832 ms (66 iters) ≈ 0% (±2.6%) — / —
future-genetic 21 ✅ 2122 ms (87 iters) ✅ 2058 ms (90 iters) 🟢 -3% — / —
future-genetic 25 ✅ 2059 ms (90 iters) ✅ 2049 ms (90 iters) ≈ -0.5% (±2.6%) — / —
naive-bayes 21 ✅ 1257 ms (136 iters) ✅ 1304 ms (132 iters) ≈ +3.7% (±33.1%) — / —
naive-bayes 25 ✅ 1028 ms (167 iters) ✅ 1014 ms (169 iters) ≈ -1.4% (±31.8%) — / —
reactors 21 ✅ 16668 ms (15 iters) ✅ 15846 ms (15 iters) ≈ -4.9% (±7.4%) — / —
reactors 25 ✅ 18281 ms (15 iters) ✅ 18391 ms (15 iters) ≈ +0.6% (±5%) — / —
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 ✅ / ✅ ✅ / ✅ 4 / 2 1961 / 1939 ✅ / ✅ ✅ / ✅
akka-uct 25 ✅ / ✅ ✅ / ✅ 6 / 1 2369 / 2031 ✅ / ✅ ✅ / ✅
finagle-chirper 21 ✅ / ✅ ✅ / ✅ 4 / 1 8227 / 8628 ✅ / ✅ ✅ / ✅
finagle-chirper 25 ✅ / ✅ ✅ / ✅ ✅ / ✅ 8367 / 8248 ✅ / ✅ ✅ / ✅
fj-kmeans 21 ✅ / ✅ ✅ / ✅ 2 / 1 1267 / 1276 ✅ / ✅ ✅ / ✅
fj-kmeans 25 ✅ / ✅ ✅ / ✅ ✅ / ✅ 1287 / 1259 ✅ / ✅ ✅ / ✅
future-genetic 21 ✅ / ✅ ✅ / ✅ 2 / 1 2932 / 3002 ✅ / ✅ ✅ / ✅
future-genetic 25 ✅ / ✅ ✅ / ✅ 2 / 2 2843 / 2845 ✅ / ✅ ✅ / ✅
naive-bayes 21 ✅ / ✅ ✅ / ✅ 2 / 4 3484 / 3550 ✅ / ✅ ✅ / ✅
naive-bayes 25 ✅ / ✅ ✅ / ✅ 2 / 4 3492 / 3488 ✅ / ✅ ✅ / ✅
reactors 21 ✅ / ✅ ✅ / ✅ 1 / 2 1638 / 1621 ✅ / ✅ ✅ / ✅
reactors 25 ✅ / ✅ ✅ / ✅ 1 / 1 1843 / 1824 ✅ / ✅ ✅ / ✅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants