Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import datadog.trace.bootstrap.instrumentation.jfr.InstrumentationBasedProfiling;
import datadog.trace.util.AgentTaskScheduler;
import datadog.trace.util.AgentThreadFactory.AgentThread;
import datadog.trace.util.JDK9ModuleAccess;
import datadog.trace.util.throwable.FatalAgentMisconfigurationError;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.lang.instrument.Instrumentation;
Expand Down Expand Up @@ -659,6 +660,8 @@ public InstallDatadogTracerCallback(
}

installDatadogMeter(initTelemetry);
// Must run before installDatadogTracer, which triggers the ddprof profiler load.
prepareDatadogProfilerContextStorage(instrumentation);
installDatadogTracer(initTelemetry, scoClass, sco);
maybeInstallLogsIntake(scoClass, sco);
maybeStartIast(instrumentation);
Expand Down Expand Up @@ -1356,6 +1359,33 @@ public void withTracer(TracerAPI tracer) {
});
}

/**
* Exports {@code jdk.internal.misc} to the classloader that loads {@code
* com.datadoghq.profiler.*} before the Datadog profiler is loaded.
*
* <p>On JDK 21+, the profiler scopes its context {@code ThreadContext} storage to the carrier
* thread using {@code jdk.internal.misc.CarrierThreadLocal}, so a mounted virtual thread resolves
* to its current carrier's record — fixing a virtual-thread context use-after-free. That type
* lives in a non-exported package, hence the export. Must run before {@code
* installDatadogTracer}, which loads the profiler via {@link
* #createProfilingContextIntegration()}.
*/
private static void prepareDatadogProfilerContextStorage(Instrumentation inst) {
try {
if (inst == null
|| !Config.get().isProfilingEnabled()
|| !Config.get().isDatadogProfilerEnabled()
|| OperatingSystem.isWindows()
|| !isJavaVersionAtLeast(21)) {
return;
Comment thread
jbachorik marked this conversation as resolved.
}
JDK9ModuleAccess.exportModuleToUnnamedModule(
inst, "java.base", new String[] {"jdk.internal.misc"}, AGENT_CLASSLOADER);
} catch (Throwable t) {
log.debug("Unable to export jdk.internal.misc for the Datadog profiler", t);
}
}

/**
* {@see com.datadog.profiling.ddprof.DatadogProfilingIntegration} must not be modified to depend
* on JFR.
Expand Down