Skip to content

profiling(ddprof): migrate context bridge to the all-native API (Phase 2)#11899

Draft
rkennke wants to merge 1 commit into
masterfrom
rkennke/profiler-all-native-context-phase2
Draft

profiling(ddprof): migrate context bridge to the all-native API (Phase 2)#11899
rkennke wants to merge 1 commit into
masterfrom
rkennke/profiler-all-native-context-phase2

Conversation

@rkennke

@rkennke rkennke commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

What

Migrates the profiler context bridge off the deprecated DirectByteBuffer (DBB) context API onto java-profiler's all-native API (setTraceContext / clearTraceContext / setContextValue / clearContextValue).

This is Phase 2 of the all-native context work (Phase 1 = DataDog/java-profiler#631).

Why

  • Fixes the virtual-thread use-after-free: the DBB path cached a DirectByteBuffer over the native OTEP record; on a carrier that a mounted virtual thread later migrated off, the record was freed while the cached buffer kept being written. The all-native API resolves the current carrier's record inside each JNI call — no cached buffer to dangle.
  • Per-activation perf: activation collapses from setContext + 2×setContextValue (3 JNI calls) into one setTraceContext (~28% faster on the combined cycle per the design-note benchmark).

Changes

  • DatadogProfilingIntegration.activate → one setTraceContext(...) carrying trace/span context + operation & resource attributes; close/clearContextclearTraceContext().
  • DatadogProfiler: setContextValue/clearContextValue/reapplyAppContext/syncNativeAppContext are now all-native. reapplyAppContext uses a per-slot native setContextValue loop — native setContextValue publishes the record (valid=1) even with no active span, so app context stays visible between spans (preserves Restore app context attributes wiped by ddprof setContext on span activation #11646). A native batch reapply is deferred to a measured follow-up (java-profiler PROF-15361).
  • AppContextSnapshot simplified to strings-only (the native path resolves each value's encoding via the process-wide cache — no cached id/utf8/snapshotTags DBB read).
  • snapshot() uses the new native copyContextTags read (no ThreadContext/DBB, so it observes native writes without resetting the record).
  • ContextSetter kept only for offsetOf + size (pure Java); no DBB usage remains.

Dependency / how to build

Requires java-profiler with the all-native API — DataDog/java-profiler#631 (ddprof ≥ the Phase-1 release). Until that ships, build/test against a local snapshot:

# in java-profiler (PR #631 branch):
./gradlew publishToMavenLocal          # com.datadoghq:ddprof:1.47.0-SNAPSHOT
# here:
./gradlew :dd-java-agent:agent-profiling:profiling-ddprof:test -PddprofUseSnapshot=true

Status / verification

  • Draft — gated on the java-profiler Phase-1 release and Linux CI verification.
  • Compiles cleanly against the local 1.47.0-SNAPSHOT.
  • The ddprof test suite (DatadogProfilerTest, …) is Linux-gated (assumeTrue(isLinux())) and was not run on the author's macOS box — needs Linux/CI to exercise behavior.

🤖 Generated with Claude Code

Switch the profiler context bridge off the deprecated DirectByteBuffer (DBB)
context API onto java-profiler's all-native API (setTraceContext /
clearTraceContext / setContextValue / clearContextValue). This eliminates the
virtual-thread use-after-free (the DBB cached buffer that dangled on carrier
migration) and folds the per-activation sequence (setContext + two
setContextValue) into a single native call.

- DatadogProfilingIntegration.activate: one setTraceContext(...) carrying
  trace/span context + operation and resource attributes (3 JNI calls -> 1);
  close/clearContext: clearTraceContext() (wipes op/resource slots too).
- DatadogProfiler: setContextValue/clearContextValue/reapplyAppContext/
  syncNativeAppContext are now all-native. reapplyAppContext uses a per-slot
  native setContextValue loop (native setContextValue publishes valid=1, so app
  context stays visible without an active span — preserves PR #11646). A native
  batch reapply is deferred to a measured follow-up (java-profiler PROF-15361).
- AppContextSnapshot simplified to strings-only (the native path resolves each
  value's encoding via the process-wide cache; no cached id/utf8/snapshotTags).
- snapshot() uses the new native copyContextTags read (no ThreadContext/DBB, so
  it observes native writes without resetting the record).
- ContextSetter kept only for offsetOf + size (pure Java); no DBB usage remains.

Requires java-profiler with the all-native API (ddprof >= the phase-1 release;
DataDog/java-profiler#631). Build/test with -PddprofUseSnapshot=true against a
local publishToMavenLocal 1.47.0-SNAPSHOT until that ships. ddprof suite is
Linux-gated (assumeTrue(isLinux)) — verify on Linux/CI.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant