diff --git a/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/CapturedContext.java b/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/CapturedContext.java index 406dae182fb..3d1b8e2af49 100644 --- a/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/CapturedContext.java +++ b/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/CapturedContext.java @@ -294,13 +294,14 @@ public void freeze(TimeoutChecker timeoutChecker) { } public Status evaluate( - String encodedProbeId, ProbeImplementation probeImplementation, String thisClassName, long startTimestamp, MethodLocation methodLocation) { Status status = - statusByProbeId.computeIfAbsent(encodedProbeId, key -> probeImplementation.createStatus()); + statusByProbeId.computeIfAbsent( + probeImplementation.getProbeId().getEncodedId(), + key -> probeImplementation.createStatus()); if (methodLocation == MethodLocation.EXIT && startTimestamp > 0) { duration = System.nanoTime() - startTimestamp; addExtension( @@ -326,6 +327,18 @@ public Status getStatus(String encodedProbeId) { return result; } + public Status getStatus(int probeIndex) { + ProbeImplementation probeImplementation = DebuggerContext.resolveProbe(probeIndex); + if (probeImplementation != null) { + return getStatus(probeImplementation.getProbeId().getEncodedId()); + } + Status result = statusByProbeId.get(ProbeImplementation.UNKNOWN.getProbeId().getEncodedId()); + if (result == null) { + return Status.EMPTY_STATUS; + } + return result; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/DebuggerContext.java b/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/DebuggerContext.java index 12ae1b21f7e..15a39ff7779 100644 --- a/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/DebuggerContext.java +++ b/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/DebuggerContext.java @@ -51,7 +51,7 @@ public String tag() { } public interface ProbeResolver { - ProbeImplementation resolve(String encodedProbeId); + ProbeImplementation resolve(int probeIndex); } public interface ClassFilter { @@ -144,16 +144,13 @@ public static void initCodeOrigin(CodeOriginRecorder codeOriginRecorder) { DebuggerContext.codeOriginRecorder = codeOriginRecorder; } - /** - * Returns the probe details based on the probe id provided. If no probe is found, try to - * re-transform the class using the callingClass parameter No-op if no implementation available - */ - public static ProbeImplementation resolveProbe(String id) { + /** Returns the probe details based on the probe idx provided. */ + public static ProbeImplementation resolveProbe(int probeIndex) { ProbeResolver resolver = probeResolver; if (resolver == null) { return null; } - return resolver.resolve(id); + return resolver.resolve(probeIndex); } /** @@ -253,7 +250,7 @@ public static DebuggerSpan createSpan(String probeId, String operationName, Stri * * @return true if can proceed to capture data */ - public static boolean isReadyToCapture(Class callingClass, String... encodedProbeIds) { + public static boolean isReadyToCapture(Class callingClass, int... probeIndices) { try { return checkAndSetInProbe(); } catch (Exception ex) { @@ -287,21 +284,17 @@ public static void evalContext( Class callingClass, long startTimestamp, MethodLocation methodLocation, - String... encodedProbeIds) { + int... probeIndices) { try { boolean needFreeze = false; - for (String encodedProbeId : encodedProbeIds) { - ProbeImplementation probeImplementation = resolveProbe(encodedProbeId); + for (int probeIndex : probeIndices) { + ProbeImplementation probeImplementation = resolveProbe(probeIndex); if (probeImplementation == null) { continue; } CapturedContext.Status status = context.evaluate( - encodedProbeId, - probeImplementation, - callingClass.getTypeName(), - startTimestamp, - methodLocation); + probeImplementation, callingClass.getTypeName(), startTimestamp, methodLocation); needFreeze |= status.shouldFreezeContext(); } // only freeze the context when we have at lest one snapshot probe, and we should send @@ -321,20 +314,16 @@ public static void evalContext( * conditions and commit snapshot to send it if needed. This is for line probes. */ public static void evalContextAndCommit( - CapturedContext context, Class callingClass, int line, String... encodedProbeIds) { + CapturedContext context, Class callingClass, int line, int... probeIndices) { try { List probeImplementations = new ArrayList<>(); - for (String encodedProbeId : encodedProbeIds) { - ProbeImplementation probeImplementation = resolveProbe(encodedProbeId); + for (int probeIndex : probeIndices) { + ProbeImplementation probeImplementation = resolveProbe(probeIndex); if (probeImplementation == null) { continue; } context.evaluate( - encodedProbeId, - probeImplementation, - callingClass.getTypeName(), - -1, - MethodLocation.DEFAULT); + probeImplementation, callingClass.getTypeName(), -1, MethodLocation.DEFAULT); probeImplementations.add(probeImplementation); } for (ProbeImplementation probeImplementation : probeImplementations) { @@ -345,9 +334,9 @@ public static void evalContextAndCommit( } } - public static void codeOrigin(String probeId) { + public static void codeOrigin(int probeIndex) { try { - ProbeImplementation probe = probeResolver.resolve(probeId); + ProbeImplementation probe = probeResolver.resolve(probeIndex); if (probe != null) { probe.commit( CapturedContext.EMPTY_CONTEXT, CapturedContext.EMPTY_CONTEXT, Collections.emptyList()); @@ -365,16 +354,16 @@ public static void commit( CapturedContext entryContext, CapturedContext exitContext, List caughtExceptions, - String... encodedProbeIds) { + int... probeIndices) { try { if (entryContext == CapturedContext.EMPTY_CONTEXT && exitContext == CapturedContext.EMPTY_CONTEXT) { // rate limited return; } - for (String encodedProbeId : encodedProbeIds) { - CapturedContext.Status entryStatus = entryContext.getStatus(encodedProbeId); - CapturedContext.Status exitStatus = exitContext.getStatus(encodedProbeId); + for (int probeIndex : probeIndices) { + CapturedContext.Status entryStatus = entryContext.getStatus(probeIndex); + CapturedContext.Status exitStatus = exitContext.getStatus(probeIndex); ProbeImplementation probeImplementation; if (entryStatus.probeImplementation != ProbeImplementation.UNKNOWN && (entryStatus.probeImplementation.getEvaluateAt() == MethodLocation.ENTRY @@ -383,7 +372,7 @@ public static void commit( } else if (exitStatus.probeImplementation.getEvaluateAt() == MethodLocation.EXIT) { probeImplementation = exitStatus.probeImplementation; } else { - throw new IllegalStateException("no probe details for " + encodedProbeId); + throw new IllegalStateException("no probe details for " + probeIndex); } probeImplementation.commit(entryContext, exitContext, caughtExceptions); } diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/ConfigurationUpdater.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/ConfigurationUpdater.java index 130aabd2ad2..6fddf056848 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/ConfigurationUpdater.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/ConfigurationUpdater.java @@ -47,6 +47,7 @@ DebuggerTransformer supply( Config tracerConfig, Configuration configuration, DebuggerTransformer.InstrumentationListener listener, + ProbeMetadata probeMetadata, DebuggerSink debuggerSink); } @@ -61,6 +62,7 @@ DebuggerTransformer supply( private volatile Configuration currentConfiguration; private DebuggerTransformer currentTransformer; private final Map appliedDefinitions = new ConcurrentHashMap<>(); + private final ProbeMetadata probeMetadata = new ProbeMetadata(); private final DebuggerSink sink; private final ClassesToRetransformFinder finder; private final String serviceName; @@ -119,6 +121,10 @@ public void handleException(String configId, Exception ex) { sink.getProbeStatusSink().addError(probeId, ex); } + ProbeMetadata getProbeMetadata() { + return probeMetadata; + } + private ProbeId extractPrefix(String prefix, String configId) { return new ProbeId(configId.substring(prefix.length()), 0); } @@ -201,7 +207,11 @@ private void installNewDefinitions(Configuration newConfiguration) { // install new probe definitions DebuggerTransformer newTransformer = transformerSupplier.supply( - Config.get(), newConfiguration, this::recordInstrumentationProgress, sink); + Config.get(), + newConfiguration, + this::recordInstrumentationProgress, + probeMetadata, + sink); instrumentation.addTransformer(newTransformer, true); currentTransformer = newTransformer; LOGGER.debug("New transformer installed"); @@ -231,6 +241,7 @@ private void retransformClasses(List> classesToBeTransformed) { private void storeDebuggerDefinitions(ConfigurationComparer changes) { for (ProbeDefinition definition : changes.getRemovedDefinitions()) { appliedDefinitions.remove(definition.getProbeId().getEncodedId()); + probeMetadata.removeProbe(definition.getProbeId().getEncodedId()); } for (ProbeDefinition definition : changes.getAddedDefinitions()) { appliedDefinitions.put(definition.getProbeId().getEncodedId(), definition); @@ -240,12 +251,12 @@ private void storeDebuggerDefinitions(ConfigurationComparer changes) { // /!\ This is called potentially by multiple threads from the instrumented code /!\ @Override - public ProbeImplementation resolve(String encodedProbeId) { - ProbeDefinition definition = appliedDefinitions.get(encodedProbeId); - if (definition == null) { - ratelimitedLogger.warn(SEND_TELEMETRY, "Cannot resolve probe id={}", encodedProbeId); + public ProbeImplementation resolve(int probeIndex) { + ProbeImplementation probeImplementation = probeMetadata.getProbe(probeIndex); + if (probeImplementation == null) { + ratelimitedLogger.warn(SEND_TELEMETRY, "Cannot resolve probe index={}", probeIndex); } - return definition; + return probeImplementation; } private static void applyRateLimiter( diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/DebuggerAgent.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/DebuggerAgent.java index 24b4ed04bde..145f8175a99 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/DebuggerAgent.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/DebuggerAgent.java @@ -394,7 +394,8 @@ static ClassFileTransformer setupInstrumentTheWorldTransformer( Config config, Instrumentation instrumentation, DebuggerSink debuggerSink) { LOGGER.info("install Instrument-The-World transformer"); DebuggerTransformer transformer = - createTransformer(config, Configuration.builder().build(), null, debuggerSink); + createTransformer( + config, Configuration.builder().build(), null, new ProbeMetadata(), debuggerSink); DebuggerContext.initProbeResolver(transformer::instrumentTheWorldResolver); instrumentation.addTransformer(transformer); return transformer; @@ -412,8 +413,9 @@ private static DebuggerTransformer createTransformer( Config config, Configuration configuration, DebuggerTransformer.InstrumentationListener listener, + ProbeMetadata probeMetadata, DebuggerSink debuggerSink) { - return new DebuggerTransformer(config, configuration, listener, debuggerSink); + return new DebuggerTransformer(config, configuration, listener, probeMetadata, debuggerSink); } static void stop() { diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/DebuggerTransformer.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/DebuggerTransformer.java index 6f23f65e7d5..250c3550a3b 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/DebuggerTransformer.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/DebuggerTransformer.java @@ -52,7 +52,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; import java.util.regex.Pattern; import net.bytebuddy.description.type.TypeDescription; @@ -99,6 +98,7 @@ public class DebuggerTransformer implements ClassFileTransformer { private final AllowListHelper allowListHelper; private final DenyListHelper denyListHelper; private final InstrumentationListener listener; + private final ProbeMetadata probeMetadata; private final DebuggerSink debuggerSink; private final boolean instrumentTheWorld; private final Set excludeClasses; @@ -107,7 +107,6 @@ public class DebuggerTransformer implements ClassFileTransformer { private final Set includeClasses; private final Set includeMethods; private final Trie includeTrie; - private final Map instrumentTheWorldProbes; private final BiConsumer> probeCreator; public interface InstrumentationListener { @@ -118,17 +117,18 @@ public DebuggerTransformer( Config config, Configuration configuration, InstrumentationListener listener, + ProbeMetadata probeMetadata, DebuggerSink debuggerSink) { this.config = config; this.definitionMatcher = new TransformerDefinitionMatcher(configuration); this.allowListHelper = new AllowListHelper(configuration.getAllowList()); this.denyListHelper = new DenyListHelper(configuration.getDenyList()); this.listener = listener; + this.probeMetadata = probeMetadata; this.debuggerSink = debuggerSink; String itwType = config.getDynamicInstrumentationInstrumentTheWorld(); this.instrumentTheWorld = itwType != null; if (this.instrumentTheWorld) { - instrumentTheWorldProbes = new ConcurrentHashMap<>(); excludeTrie = new Trie(); excludeClasses = new HashSet<>(); excludeMethods = new HashSet<>(); @@ -157,7 +157,6 @@ public DebuggerTransformer( probeCreator = null; } } else { - instrumentTheWorldProbes = null; excludeTrie = null; excludeClasses = null; excludeMethods = null; @@ -169,11 +168,13 @@ public DebuggerTransformer( } // Used only for tests - public DebuggerTransformer(Config config, Configuration configuration) { + public DebuggerTransformer( + Config config, ProbeMetadata probeMetadata, Configuration configuration) { this( config, configuration, null, + probeMetadata, new DebuggerSink( config, "", @@ -370,7 +371,6 @@ private void createMethodProbe(MethodInfo methodInfo, List prob .captureSnapshot(false) .build(); probes.add(probe); - instrumentTheWorldProbes.put(probe.getProbeId().getEncodedId(), probe); } private void createLineProbes(MethodInfo methodInfo, List probes) { @@ -391,7 +391,6 @@ private void createLineProbes(MethodInfo methodInfo, List probe .captureSnapshot(false) .build(); probes.add(probe); - instrumentTheWorldProbes.put(probe.getProbeId().getEncodedId(), probe); } } @@ -410,11 +409,8 @@ private synchronized void writeToInstrumentationLog(String classFilePath) { } } - public ProbeImplementation instrumentTheWorldResolver(String id) { - if (instrumentTheWorldProbes == null) { - return null; - } - return instrumentTheWorldProbes.get(id); + public ProbeImplementation instrumentTheWorldResolver(int probeIndex) { + return probeMetadata.getProbe(probeIndex); } private boolean isExcludedFromTransformation(String classFilePath) { @@ -662,7 +658,8 @@ private InstrumentationResult applyInstrumentation( for (ToInstrumentInfo toInstrumentInfo : toInstruments) { ProbeDefinition definition = toInstrumentInfo.definition; List probeDiagnostics = diagnostics.get(definition.getProbeId()); - status = definition.instrument(methodInfo, probeDiagnostics, toInstrumentInfo.probeIds); + status = + definition.instrument(methodInfo, probeDiagnostics, toInstrumentInfo.probeIndices); } } catch (Throwable t) { LOGGER.warn("Exception during instrumentation: ", t); @@ -676,11 +673,11 @@ private InstrumentationResult applyInstrumentation( static class ToInstrumentInfo { final ProbeDefinition definition; - final List probeIds; + final List probeIndices; - ToInstrumentInfo(ProbeDefinition definition, List probeIds) { + ToInstrumentInfo(ProbeDefinition definition, List probeIndices) { this.definition = definition; - this.probeIds = probeIds; + this.probeIndices = probeIndices; } } @@ -720,11 +717,13 @@ private List filterAndSortDefinitions( capturedContextProbes.add(definition); } } else { - toInstrument.add(new ToInstrumentInfo(definition, singletonList(definition.getProbeId()))); + int idx = probeMetadata.addProbe(definition); + toInstrument.add(new ToInstrumentInfo(definition, singletonList(idx))); } } - processCapturedContextLineProbes(capturedContextLineProbes, toInstrument); - processCapturedContextMethodProbes(classFileLines, capturedContextProbes, toInstrument); + processCapturedContextLineProbes(capturedContextLineProbes, probeMetadata, toInstrument); + processCapturedContextMethodProbes( + classFileLines, capturedContextProbes, probeMetadata, toInstrument); // ordering: metric < log < span decoration < span toInstrument.sort( (info1, info2) -> { @@ -735,29 +734,36 @@ private List filterAndSortDefinitions( return toInstrument; } - private void processCapturedContextMethodProbes( + private static void processCapturedContextMethodProbes( ClassFileLines classFileLines, List capturedContextProbes, + ProbeMetadata probeMetadata, List toInstrument) { if (capturedContextProbes.isEmpty()) { return; } - List probesIds = - capturedContextProbes.stream().map(ProbeDefinition::getProbeId).collect(toList()); + List probeIndices = new ArrayList<>(); + for (ProbeDefinition definition : capturedContextProbes) { + probeIndices.add(probeMetadata.addProbe(definition)); + } ProbeDefinition referenceDefinition = selectReferenceDefinition(capturedContextProbes, classFileLines); - toInstrument.add(new ToInstrumentInfo(referenceDefinition, probesIds)); + toInstrument.add(new ToInstrumentInfo(referenceDefinition, probeIndices)); } private static void processCapturedContextLineProbes( - Map> lineProbes, List toInstrument) { + Map> lineProbes, + ProbeMetadata probeMetadata, + List toInstrument) { for (Map.Entry> entry : lineProbes.entrySet()) { if (entry.getValue().isEmpty()) { continue; } - List probeIds = - entry.getValue().stream().map(ProbeDefinition::getProbeId).collect(toList()); - toInstrument.add(new ToInstrumentInfo(entry.getValue().get(0), probeIds)); + List probeIndices = new ArrayList<>(); + for (ProbeDefinition definition : entry.getValue()) { + probeIndices.add(probeMetadata.addProbe(definition)); + } + toInstrument.add(new ToInstrumentInfo(entry.getValue().get(0), probeIndices)); } } @@ -766,7 +772,7 @@ private static void processCapturedContextLineProbes( // match the type of the probe to instrument: if at least one probe is LogProbe then we are // creating a LogProbe definition. The synthetic definition contains the union of all the capture, // snapshot and evaluateAt parameters. - private ProbeDefinition selectReferenceDefinition( + private static ProbeDefinition selectReferenceDefinition( List capturedContextProbes, ClassFileLines classFileLines) { boolean hasLogProbe = false; boolean hasOnlyExceptionProbe = @@ -816,7 +822,8 @@ private ProbeDefinition selectReferenceDefinition( .build(); } - private LogProbe.Capture mergeCapture(LogProbe.Capture current, LogProbe.Capture newCapture) { + private static LogProbe.Capture mergeCapture( + LogProbe.Capture current, LogProbe.Capture newCapture) { if (current == null) { return newCapture; } diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/ProbeMetadata.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/ProbeMetadata.java new file mode 100644 index 00000000000..f46cd3c8030 --- /dev/null +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/ProbeMetadata.java @@ -0,0 +1,70 @@ +package com.datadog.debugger.agent; + +import datadog.trace.bootstrap.debugger.ProbeImplementation; +import java.util.concurrent.atomic.AtomicReferenceArray; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ProbeMetadata { + private static final Logger LOGGER = LoggerFactory.getLogger(ProbeMetadata.class); + + private int size; + private Object lock = new Object(); + private volatile AtomicReferenceArray probeImplementations = + new AtomicReferenceArray<>(64); + + public int addProbe(ProbeImplementation probeImplementation) { + synchronized (lock) { + int len = probeImplementations.length(); + if (size >= len) { + AtomicReferenceArray newArray = new AtomicReferenceArray<>(len * 2); + for (int i = 0; i < len; i++) { + newArray.set(i, probeImplementations.get(i)); + } + probeImplementations = newArray; + } + int idx = 0; + while (probeImplementations.get(idx) != null) { + idx++; + } + probeImplementations.set(idx, probeImplementation); + LOGGER.debug( + "Assigned probeId={} to ProbeMetadata Idx={}", + probeImplementation.getProbeId().getEncodedId(), + idx); + size++; + return idx; + } + } + + public void removeProbe(int idx) { + synchronized (lock) { + probeImplementations.set(idx, null); + size--; + } + } + + public void removeProbe(String encodedProbeId) { + synchronized (lock) { + for (int i = 0; i < probeImplementations.length(); i++) { + ProbeImplementation probeImplementation = probeImplementations.get(i); + if (probeImplementation != null + && probeImplementation.getProbeId().getEncodedId().equals(encodedProbeId)) { + probeImplementations.set(i, null); + size--; + return; + } + } + } + } + + public ProbeImplementation getProbe(int idx) { + return probeImplementations.get(idx); + } + + public int size() { + synchronized (lock) { + return size; + } + } +} diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/CapturedContextInstrumentor.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/CapturedContextInstrumentor.java index 09d775683a6..0f5c7825502 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/CapturedContextInstrumentor.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/CapturedContextInstrumentor.java @@ -13,10 +13,10 @@ import static com.datadog.debugger.instrumentation.Types.CAPTURE_THROWABLE_TYPE; import static com.datadog.debugger.instrumentation.Types.CLASS_TYPE; import static com.datadog.debugger.instrumentation.Types.DEBUGGER_CONTEXT_TYPE; +import static com.datadog.debugger.instrumentation.Types.INT_ARRAY_TYPE; import static com.datadog.debugger.instrumentation.Types.METHOD_LOCATION_TYPE; import static com.datadog.debugger.instrumentation.Types.OBJECT_TYPE; import static com.datadog.debugger.instrumentation.Types.REFLECTIVE_FIELD_VALUE_RESOLVER_TYPE; -import static com.datadog.debugger.instrumentation.Types.STRING_ARRAY_TYPE; import static com.datadog.debugger.instrumentation.Types.STRING_TYPE; import static com.datadog.debugger.instrumentation.Types.THROWABLE_TYPE; import static org.objectweb.asm.Type.BOOLEAN_TYPE; @@ -33,7 +33,6 @@ import datadog.trace.api.Config; import datadog.trace.bootstrap.debugger.Limits; import datadog.trace.bootstrap.debugger.MethodLocation; -import datadog.trace.bootstrap.debugger.ProbeId; import datadog.trace.bootstrap.debugger.util.Redaction; import java.lang.reflect.Field; import java.util.ArrayList; @@ -50,6 +49,7 @@ import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.InsnList; import org.objectweb.asm.tree.InsnNode; +import org.objectweb.asm.tree.IntInsnNode; import org.objectweb.asm.tree.JumpInsnNode; import org.objectweb.asm.tree.LabelNode; import org.objectweb.asm.tree.LocalVariableNode; @@ -76,11 +76,11 @@ public CapturedContextInstrumentor( ProbeDefinition definition, MethodInfo methodInfo, List diagnostics, - List probeIds, + List probeIndices, boolean captureSnapshot, boolean captureEntry, Limits limits) { - super(definition, methodInfo, diagnostics, probeIds); + super(definition, methodInfo, diagnostics, probeIndices); this.captureSnapshot = captureSnapshot; this.captureEntry = captureEntry; this.limits = limits; @@ -142,7 +142,7 @@ private boolean addLineCaptures(ClassFileLines classFileLines) { } ldc(insnList, Type.getObjectType(classNode.name)); // stack [class, array] - pushProbesIds(insnList); + pushProbeIndices(insnList); // stack [array] invokeStatic( insnList, @@ -150,7 +150,7 @@ private boolean addLineCaptures(ClassFileLines classFileLines) { "isReadyToCapture", Type.BOOLEAN_TYPE, CLASS_TYPE, - STRING_ARRAY_TYPE); + INT_ARRAY_TYPE); // stack [boolean] LabelNode targetNode = new LabelNode(); insnList.add(new JumpInsnNode(Opcodes.IFEQ, targetNode)); @@ -163,7 +163,7 @@ private boolean addLineCaptures(ClassFileLines classFileLines) { // stack [capturedcontext, class] ldc(insnList, sourceLine.getFrom()); // stack [capturedcontext, class, int] - pushProbesIds(insnList); + pushProbeIndices(insnList); // stack [capturedcontext, class, int, array] invokeStatic( insnList, @@ -173,7 +173,7 @@ private boolean addLineCaptures(ClassFileLines classFileLines) { CAPTURED_CONTEXT_TYPE, CLASS_TYPE, INT_TYPE, - STRING_ARRAY_TYPE); + INT_ARRAY_TYPE); // stack [] invokeStatic(insnList, DEBUGGER_CONTEXT_TYPE, "disableInProbe", VOID_TYPE); LabelNode inProbeEndLabel = new LabelNode(); @@ -279,7 +279,7 @@ protected InsnList getBeforeReturnInsnList(AbstractInsnNode node) { // stack [ret_value, capturedcontext, class, long] getStatic(insnList, METHOD_LOCATION_TYPE, "EXIT"); // stack [ret_value, capturedcontext, class, long, methodlocation] - pushProbesIds(insnList); + pushProbeIndices(insnList); // stack [ret_value, capturedcontext, class, long, methodlocation, array] invokeStatic( insnList, @@ -290,7 +290,7 @@ protected InsnList getBeforeReturnInsnList(AbstractInsnNode node) { CLASS_TYPE, LONG_TYPE, METHOD_LOCATION_TYPE, - STRING_ARRAY_TYPE); + INT_ARRAY_TYPE); // stack [ret_value] invokeStatic(insnList, DEBUGGER_CONTEXT_TYPE, "disableInProbe", VOID_TYPE); insnList.add(new JumpInsnNode(Opcodes.GOTO, gotoNode)); @@ -325,7 +325,7 @@ private InsnList commit() { insnList.add(new InsnNode(Opcodes.ACONST_NULL)); } // stack [capturedcontext, capturedcontext, list] - pushProbesIds(insnList); + pushProbeIndices(insnList); // stack [capturedcontext, capturedcontext, array] invokeStatic( insnList, @@ -335,7 +335,7 @@ private InsnList commit() { CAPTURED_CONTEXT_TYPE, CAPTURED_CONTEXT_TYPE, getType(List.class), - getType(String[].class)); + INT_ARRAY_TYPE); // stack [] return insnList; } @@ -374,7 +374,7 @@ protected void addFinallyHandler(LabelNode startLabel, LabelNode endLabel) { // stack [exception, capturedcontext, class, long] getStatic(handler, METHOD_LOCATION_TYPE, "EXIT"); // stack [exception, capturedcontext, class, long, methodlocation] - pushProbesIds(handler); + pushProbeIndices(handler); // stack [exception, capturedcontext, class, long, methodlocation, array] invokeStatic( handler, @@ -385,7 +385,7 @@ protected void addFinallyHandler(LabelNode startLabel, LabelNode endLabel) { CLASS_TYPE, LONG_TYPE, METHOD_LOCATION_TYPE, - STRING_ARRAY_TYPE); + INT_ARRAY_TYPE); // stack [exception] invokeStatic(handler, DEBUGGER_CONTEXT_TYPE, "disableInProbe", VOID_TYPE); // stack [exception] @@ -418,7 +418,7 @@ private void instrumentMethodEnter() { } ldc(insnList, Type.getObjectType(classNode.name)); // stack [class] - pushProbesIds(insnList); + pushProbeIndices(insnList); // stack [class, array] invokeStatic( insnList, @@ -426,7 +426,7 @@ private void instrumentMethodEnter() { "isReadyToCapture", Type.BOOLEAN_TYPE, CLASS_TYPE, - STRING_ARRAY_TYPE); + INT_ARRAY_TYPE); // stack [boolean] LabelNode targetNode = new LabelNode(); LabelNode gotoNode = new LabelNode(); @@ -443,7 +443,7 @@ private void instrumentMethodEnter() { // stack [capturedcontext, class, long] getStatic(insnList, METHOD_LOCATION_TYPE, "ENTRY"); // stack [capturedcontext, class, long, methodlocation] - pushProbesIds(insnList); + pushProbeIndices(insnList); // stack [capturedcontext, class, long, methodlocation, array] invokeStatic( insnList, @@ -454,7 +454,7 @@ private void instrumentMethodEnter() { CLASS_TYPE, LONG_TYPE, METHOD_LOCATION_TYPE, - STRING_ARRAY_TYPE); + INT_ARRAY_TYPE); invokeStatic(insnList, DEBUGGER_CONTEXT_TYPE, "disableInProbe", VOID_TYPE); LabelNode inProbeEndLabel = new LabelNode(); insnList.add(inProbeEndLabel); @@ -501,19 +501,19 @@ private void createInProbeFinallyHandler(LabelNode inProbeStartLabel, LabelNode finallyBlocks.add(new FinallyBlock(inProbeStartLabel, inProbeEndLabel, handlerLabel)); } - private void pushProbesIds(InsnList insnList) { - ldc(insnList, probeIds.size()); // array size + private void pushProbeIndices(InsnList insnList) { + ldc(insnList, probeIndices.size()); // array size // stack [int] - insnList.add(new TypeInsnNode(Opcodes.ANEWARRAY, STRING_TYPE.getInternalName())); + insnList.add(new IntInsnNode(Opcodes.NEWARRAY, Opcodes.T_INT)); // stack [array] - for (int i = 0; i < probeIds.size(); i++) { + for (int i = 0; i < probeIndices.size(); i++) { insnList.add(new InsnNode(Opcodes.DUP)); // stack [array, array] ldc(insnList, i); // index // stack [array, array, int] - ldc(insnList, probeIds.get(i).getEncodedId()); - // stack [array, array, int, string] - insnList.add(new InsnNode(Opcodes.AASTORE)); + ldc(insnList, probeIndices.get(i).intValue()); + // stack [array, array, int, int] + insnList.add(new InsnNode(Opcodes.IASTORE)); // stack [array] } } diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/CodeOriginInstrumentor.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/CodeOriginInstrumentor.java index 4ef2a5a4c63..364470301b3 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/CodeOriginInstrumentor.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/CodeOriginInstrumentor.java @@ -3,7 +3,6 @@ import static com.datadog.debugger.instrumentation.ASMHelper.invokeStatic; import static com.datadog.debugger.instrumentation.ASMHelper.ldc; import static com.datadog.debugger.instrumentation.Types.DEBUGGER_CONTEXT_TYPE; -import static com.datadog.debugger.instrumentation.Types.STRING_TYPE; import static java.lang.Integer.parseInt; import static java.lang.String.format; @@ -11,7 +10,6 @@ import com.datadog.debugger.probe.CodeOriginProbe; import com.datadog.debugger.probe.ProbeDefinition; import datadog.trace.bootstrap.debugger.DebuggerContext; -import datadog.trace.bootstrap.debugger.ProbeId; import java.util.List; import java.util.ListIterator; import org.objectweb.asm.Type; @@ -35,8 +33,8 @@ public class CodeOriginInstrumentor extends Instrumentor { } public CodeOriginInstrumentor( - ProbeDefinition definition, MethodInfo methodInfo, List probeIds) { - super(definition, methodInfo, null, probeIds); + ProbeDefinition definition, MethodInfo methodInfo, List probeIndices) { + super(definition, methodInfo, null, probeIndices); } @Override @@ -56,8 +54,8 @@ private static String buildDescription(AbstractInsnNode node) { private InsnList codeOriginCall() { InsnList insnList = new InsnList(); - ldc(insnList, probeIds.get(0).getEncodedId()); - invokeStatic(insnList, DEBUGGER_CONTEXT_TYPE, "codeOrigin", Type.VOID_TYPE, STRING_TYPE); + ldc(insnList, probeIndices.get(0)); + invokeStatic(insnList, DEBUGGER_CONTEXT_TYPE, "codeOrigin", Type.VOID_TYPE, Type.INT_TYPE); return insnList; } diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/ExceptionInstrumentor.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/ExceptionInstrumentor.java index 74f9963943c..938125a2f94 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/ExceptionInstrumentor.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/ExceptionInstrumentor.java @@ -2,7 +2,6 @@ import com.datadog.debugger.probe.ProbeDefinition; import datadog.trace.bootstrap.debugger.Limits; -import datadog.trace.bootstrap.debugger.ProbeId; import java.util.List; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.InsnList; @@ -13,8 +12,8 @@ public ExceptionInstrumentor( ProbeDefinition definition, MethodInfo methodInfo, List diagnostics, - List probeIds) { - super(definition, methodInfo, diagnostics, probeIds, true, false, Limits.DEFAULT); + List probeIndices) { + super(definition, methodInfo, diagnostics, probeIndices, true, false, Limits.DEFAULT); } @Override diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/Instrumentor.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/Instrumentor.java index 358c820b049..b9aa52d8a4e 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/Instrumentor.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/Instrumentor.java @@ -9,7 +9,6 @@ import com.datadog.debugger.instrumentation.DiagnosticMessage.Kind; import com.datadog.debugger.probe.ProbeDefinition; import com.datadog.debugger.util.ClassFileLines; -import datadog.trace.bootstrap.debugger.ProbeId; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -40,7 +39,7 @@ public abstract class Instrumentor { protected final MethodNode methodNode; protected final ClassFileLines classFileLines; protected final List diagnostics; - protected final List probeIds; + protected final List probeIndices; protected final boolean isStatic; protected final LabelNode methodEnterLabel; protected int localVarBaseOffset; @@ -54,14 +53,14 @@ public Instrumentor( ProbeDefinition definition, MethodInfo methodInfo, List diagnostics, - List probeIds) { + List probeIndices) { this.definition = definition; this.classLoader = methodInfo.getClassLoader(); this.classNode = methodInfo.getClassNode(); this.methodNode = methodInfo.getMethodNode(); this.classFileLines = methodInfo.getClassFileLines(); this.diagnostics = diagnostics; - this.probeIds = probeIds; + this.probeIndices = probeIndices; isStatic = (methodNode.access & Opcodes.ACC_STATIC) != 0; methodEnterLabel = insertMethodEnterLabel(); argOffset = isStatic ? 0 : 1; diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/MetricInstrumentor.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/MetricInstrumentor.java index 11c46673318..d8fe8297f9c 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/MetricInstrumentor.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/MetricInstrumentor.java @@ -52,7 +52,6 @@ import com.datadog.debugger.probe.Where; import com.datadog.debugger.util.ClassFileLines; import datadog.trace.bootstrap.debugger.MethodLocation; -import datadog.trace.bootstrap.debugger.ProbeId; import datadog.trace.bootstrap.debugger.el.ValueReferences; import java.lang.reflect.Field; import java.util.ArrayList; @@ -88,8 +87,8 @@ public MetricInstrumentor( MetricProbe metricProbe, MethodInfo methodInfo, List diagnostics, - List probeIds) { - super(metricProbe, methodInfo, diagnostics, probeIds); + List probeIndices) { + super(metricProbe, methodInfo, diagnostics, probeIndices); this.metricProbe = metricProbe; } diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/SpanInstrumentor.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/SpanInstrumentor.java index bf7187bade8..1800d53b701 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/SpanInstrumentor.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/SpanInstrumentor.java @@ -12,7 +12,6 @@ import com.datadog.debugger.probe.SpanProbe; import com.datadog.debugger.probe.Where; import com.datadog.debugger.util.ClassFileLines; -import datadog.trace.bootstrap.debugger.ProbeId; import java.util.List; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; @@ -29,8 +28,8 @@ public SpanInstrumentor( SpanProbe spanProbe, MethodInfo methodInfo, List diagnostics, - List probeIds) { - super(spanProbe, methodInfo, diagnostics, probeIds); + List probeIndices) { + super(spanProbe, methodInfo, diagnostics, probeIndices); } @Override diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/Types.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/Types.java index 61a72ddaa0b..ac156b2c7cf 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/Types.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/Types.java @@ -47,6 +47,7 @@ public final class Types { // common Type constants public static final Type STRING_TYPE = Type.getType(String.class); public static final Type OBJECT_ARRAY_TYPE = Type.getType(Object[].class); + public static final Type INT_ARRAY_TYPE = Type.getType(int[].class); public static final Type STRING_ARRAY_TYPE = Type.getType(String[].class); public static final Type OBJECT_TYPE = Type.getType(Object.class); public static final Type COLLECTION_TYPE = Type.getType(Collection.class); diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/CodeOriginProbe.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/CodeOriginProbe.java index e877ae5b909..8e204ee114f 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/CodeOriginProbe.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/CodeOriginProbe.java @@ -35,8 +35,8 @@ public CodeOriginProbe(ProbeId probeId, boolean entry, Where where) { @Override public Status instrument( - MethodInfo methodInfo, List diagnostics, List probeIds) { - return new CodeOriginInstrumentor(this, methodInfo, probeIds).instrument(); + MethodInfo methodInfo, List diagnostics, List probeIndices) { + return new CodeOriginInstrumentor(this, methodInfo, probeIndices).instrument(); } @Override diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/ExceptionProbe.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/ExceptionProbe.java index 59b8e9eb41c..715993adc87 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/ExceptionProbe.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/ExceptionProbe.java @@ -53,8 +53,8 @@ public ExceptionProbe( @Override public InstrumentationResult.Status instrument( - MethodInfo methodInfo, List diagnostics, List probeIds) { - return new ExceptionInstrumentor(this, methodInfo, diagnostics, probeIds).instrument(); + MethodInfo methodInfo, List diagnostics, List probeIndices) { + return new ExceptionInstrumentor(this, methodInfo, diagnostics, probeIndices).instrument(); } @Override diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/LogProbe.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/LogProbe.java index 0bfa18528df..a5711a872d9 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/LogProbe.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/LogProbe.java @@ -443,14 +443,14 @@ public Sampling getSampling() { @Override public InstrumentationResult.Status instrument( - MethodInfo methodInfo, List diagnostics, List probeIds) { + MethodInfo methodInfo, List diagnostics, List probeIndices) { // only capture entry values if explicitly not at Exit. By default, we are using evaluateAt=EXIT boolean captureEntry = getEvaluateAt() != MethodLocation.EXIT; return new CapturedContextInstrumentor( this, methodInfo, diagnostics, - probeIds, + probeIndices, isCaptureSnapshot(), captureEntry, toLimits(getCapture())) diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/MetricProbe.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/MetricProbe.java index 556a2355c1d..3d4d92da7ff 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/MetricProbe.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/MetricProbe.java @@ -136,8 +136,8 @@ public ValueScript getValue() { @Override public InstrumentationResult.Status instrument( - MethodInfo methodInfo, List diagnostics, List probeIds) { - return new MetricInstrumentor(this, methodInfo, diagnostics, probeIds).instrument(); + MethodInfo methodInfo, List diagnostics, List probeIndices) { + return new MetricInstrumentor(this, methodInfo, diagnostics, probeIndices).instrument(); } public static Builder builder() { diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/ProbeDefinition.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/ProbeDefinition.java index f493634a43c..e75b8374eaa 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/ProbeDefinition.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/ProbeDefinition.java @@ -128,7 +128,7 @@ private static void initTagMap(Map tagMap, Tag[] tags) { } public abstract InstrumentationResult.Status instrument( - MethodInfo methodInfo, List diagnostics, List probeIds); + MethodInfo methodInfo, List diagnostics, List probeIndices); @Override public ProbeLocation getLocation() { diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/SpanDecorationProbe.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/SpanDecorationProbe.java index b2a1ec96bc0..fa4f2e489bb 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/SpanDecorationProbe.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/SpanDecorationProbe.java @@ -134,10 +134,10 @@ public SpanDecorationProbe( @Override public InstrumentationResult.Status instrument( - MethodInfo methodInfo, List diagnostics, List probeIds) { + MethodInfo methodInfo, List diagnostics, List probeIndices) { boolean captureEntry = evaluateAt != MethodLocation.EXIT; return new CapturedContextInstrumentor( - this, methodInfo, diagnostics, probeIds, false, captureEntry, Limits.DEFAULT) + this, methodInfo, diagnostics, probeIndices, false, captureEntry, Limits.DEFAULT) .instrument(); } diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/SpanProbe.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/SpanProbe.java index 941c1f6fa70..c7973f6d221 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/SpanProbe.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/SpanProbe.java @@ -24,8 +24,8 @@ public SpanProbe(String language, ProbeId probeId, String[] tagStrs, Where where @Override public InstrumentationResult.Status instrument( - MethodInfo methodInfo, List diagnostics, List probeIds) { - return new SpanInstrumentor(this, methodInfo, diagnostics, probeIds).instrument(); + MethodInfo methodInfo, List diagnostics, List probeIndices) { + return new SpanInstrumentor(this, methodInfo, diagnostics, probeIndices).instrument(); } @Generated diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/TriggerProbe.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/TriggerProbe.java index b4dd186dabf..0257768dfd2 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/TriggerProbe.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/probe/TriggerProbe.java @@ -53,9 +53,9 @@ public TriggerProbe(ProbeId probeId, Where where) { @Override public InstrumentationResult.Status instrument( - MethodInfo methodInfo, List diagnostics, List probeIds) { + MethodInfo methodInfo, List diagnostics, List probeIndices) { return new CapturedContextInstrumentor( - this, methodInfo, diagnostics, probeIds, false, false, null) + this, methodInfo, diagnostics, probeIndices, false, false, null) .instrument(); } diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/CapturedSnapshotTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/CapturedSnapshotTest.java index 705f55ea5fa..d9ec1889836 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/CapturedSnapshotTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/CapturedSnapshotTest.java @@ -219,7 +219,7 @@ public void resolutionFails() throws IOException, URISyntaxException { int line = getLineForLineProbe(CLASS_NAME, LINE_PROBE_ID1); TestSnapshotListener listener = installLineProbe(LINE_PROBE_ID1, CLASS_NAME, line); DebuggerAgentHelper.injectSink(listener); - DebuggerContext.initProbeResolver((encodedProbeId) -> null); + DebuggerContext.initProbeResolver(probeIndex -> null); Class testClass = compileAndLoadClass(CLASS_NAME); int result = Reflect.onClass(testClass).call("main", "1").get(); assertEquals(3, result); @@ -236,7 +236,7 @@ public void resolutionThrows() throws IOException, URISyntaxException { TestSnapshotListener listener = installProbes(lineProbe, methodProbe); DebuggerAgentHelper.injectSink(listener); DebuggerContext.initProbeResolver( - (encodedProbeId) -> { + probeIndex -> { throw new IllegalArgumentException("oops"); }); Class testClass = compileAndLoadClass(CLASS_NAME); diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/CapturingTestBase.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/CapturingTestBase.java index 3a05d80656b..1012968e241 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/CapturingTestBase.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/CapturingTestBase.java @@ -23,7 +23,6 @@ import datadog.trace.bootstrap.debugger.DebuggerContext; import datadog.trace.bootstrap.debugger.MethodLocation; import datadog.trace.bootstrap.debugger.ProbeId; -import datadog.trace.bootstrap.debugger.ProbeImplementation; import datadog.trace.bootstrap.debugger.ProbeRateLimiter; import datadog.trace.bootstrap.debugger.util.Redaction; import java.io.File; @@ -65,16 +64,12 @@ public class CapturingTestBase { MoshiHelper.createGenericAdapter(); protected Config config; - protected ConfigurationUpdater configurationUpdater; - protected ClassFileTransformer currentTransformer; - protected Instrumentation instr; - protected MockInstrumentationListener instrumentationListener; - protected ProbeStatusSink probeStatusSink; + protected ProbeMetadata probeMetadata = new ProbeMetadata(); @AfterEach public void after() { @@ -359,11 +354,15 @@ protected TestSnapshotListener installProbes(Configuration configuration) { new DebuggerSink(config, probeStatusSink), new ClassesToRetransformFinder()); currentTransformer = - new DebuggerTransformer(config, configuration, instrumentationListener, listener); + new DebuggerTransformer( + config, + configuration, + instrumentationListener, + configurationUpdater.getProbeMetadata(), + listener); instr.addTransformer(currentTransformer); DebuggerAgentHelper.injectSink(listener); - DebuggerContext.initProbeResolver( - (encodedId) -> resolver(encodedId, configuration.getDefinitions())); + DebuggerContext.initProbeResolver(configurationUpdater::resolve); DebuggerContext.initClassFilter(new DenyListHelper(null)); DebuggerContext.initValueSerializer(new JsonSnapshotSerializer()); @@ -389,16 +388,6 @@ public static Config getConfig() { return config; } - public ProbeImplementation resolver(String encodedId, List probes) { - for (ProbeDefinition probe : probes) { - if (probe.getProbeId().getEncodedId().equals(encodedId)) { - return probe; - } - } - - return configurationUpdater.resolve(encodedId); - } - protected TestSnapshotListener installMethodProbeAtExit( String typeName, String methodName, String signature) { LogProbe logProbes = diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/ConfigurationUpdaterTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/ConfigurationUpdaterTest.java index 9a06b52dd98..3bc4cf4e4df 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/ConfigurationUpdaterTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/ConfigurationUpdaterTest.java @@ -330,7 +330,7 @@ public void acceptDeleteProbeSameClass() throws UnmodifiableClassException { ConfigurationUpdater configurationUpdater = new ConfigurationUpdater( inst, - (tracerConfig, configuration, listener, debuggerSink) -> { + (tracerConfig, configuration, listener, probeMetadata, debuggerSink) -> { assertEquals(expectedDefinitions.get(), configuration.getDefinitions().size()); return transformer; }, @@ -399,7 +399,8 @@ public void resolve() { .build()); logProbes.get(0).buildLocation(null); configurationUpdater.accept(REMOTE_CONFIG, logProbes); - ProbeImplementation probeImplementation = configurationUpdater.resolve(PROBE_ID.getEncodedId()); + configurationUpdater.getProbeMetadata().addProbe(logProbes.get(0)); + ProbeImplementation probeImplementation = configurationUpdater.resolve(0); Assertions.assertEquals( PROBE_ID.getEncodedId(), probeImplementation.getProbeId().getEncodedId()); Assertions.assertEquals("java.lang.String", probeImplementation.getLocation().getType()); @@ -417,8 +418,7 @@ public void resolveFails() throws UnmodifiableClassException { configurationUpdater.accept(REMOTE_CONFIG, logProbes); verify(inst).retransformClasses(eq(String.class)); // simulate that there is a snapshot probe instrumentation left in HashMap class - ProbeImplementation probeImplementation = - configurationUpdater.resolve(PROBE_ID2.getEncodedId()); + ProbeImplementation probeImplementation = configurationUpdater.resolve(1); Assertions.assertNull(probeImplementation); } @@ -627,6 +627,7 @@ private DebuggerTransformer createTransformer( Config tracerConfig, Configuration configuration, DebuggerTransformer.InstrumentationListener listener, + ProbeMetadata probeMetadata, DebuggerSink debuggerSink) { return transformer; } diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/DebuggerTransformerTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/DebuggerTransformerTest.java index 55d08740941..dbed057349f 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/DebuggerTransformerTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/DebuggerTransformerTest.java @@ -155,7 +155,9 @@ public void testDump() { LogProbe.builder().where("java.util.ArrayList", "add").probeId("", 0).build(); DebuggerTransformer debuggerTransformer = new DebuggerTransformer( - config, new Configuration(SERVICE_NAME, Collections.singletonList(logProbe))); + config, + new ProbeMetadata(), + new Configuration(SERVICE_NAME, Collections.singletonList(logProbe))); debuggerTransformer.transform( ClassLoader.getSystemClassLoader(), "java.util.ArrayList", @@ -201,7 +203,8 @@ private void doTestMultiProbes( logProbes.add(logProbe); } Configuration configuration = new Configuration(SERVICE_NAME, logProbes); - DebuggerTransformer debuggerTransformer = new DebuggerTransformer(config, configuration); + DebuggerTransformer debuggerTransformer = + new DebuggerTransformer(config, new ProbeMetadata(), configuration); for (ProbeTestInfo probeInfo : probeInfos) { byte[] newClassBuffer = debuggerTransformer.transform( @@ -255,6 +258,7 @@ public void testBlockedProbes() { config, configuration, ((definition, result) -> lastResult.set(result)), + new ProbeMetadata(), new DebuggerSink( config, new ProbeStatusSink(config, config.getFinalDebuggerSnapshotUrl(), false))); byte[] newClassBuffer = @@ -283,6 +287,7 @@ public void classBeingRedefinedNull() { config, configuration, ((definition, result) -> lastResult.set(result)), + new ProbeMetadata(), new DebuggerSink( config, new ProbeStatusSink(config, config.getFinalDebuggerSnapshotUrl(), false))); byte[] newClassBuffer = @@ -319,7 +324,11 @@ public void classGenerationFailed() { TestSnapshotListener listener = new TestSnapshotListener(config, probeStatusSink); DebuggerTransformer debuggerTransformer = new DebuggerTransformer( - config, configuration, ((definition, result) -> lastResult.set(result)), listener); + config, + configuration, + ((definition, result) -> lastResult.set(result)), + new ProbeMetadata(), + listener); DebuggerAgentHelper.injectSink(listener); byte[] newClassBuffer = debuggerTransformer.transform( @@ -365,6 +374,7 @@ public void ordering() { invocationOrder.add(definition); } }, + new ProbeMetadata(), new DebuggerSink( config, new ProbeStatusSink(config, config.getFinalDebuggerSnapshotUrl(), false))); debuggerTransformer.transform( @@ -412,7 +422,7 @@ public MockProbe(ProbeId probeId, Where where) { @Override public InstrumentationResult.Status instrument( - MethodInfo methodInfo, List diagnostics, List probeIds) { + MethodInfo methodInfo, List diagnostics, List probeIndices) { methodInfo .getMethodNode() .instructions diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/LogProbesInstrumentationTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/LogProbesInstrumentationTest.java index 407e2242383..2cb3509af26 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/LogProbesInstrumentationTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/LogProbesInstrumentationTest.java @@ -564,13 +564,12 @@ private TestSnapshotListener installProbes(Configuration configuration) { .thenReturn("http://localhost:8126/debugger/v1/input"); when(config.getFinalDebuggerSymDBUrl()).thenReturn("http://localhost:8126/symdb/v1/input"); when(config.getDynamicInstrumentationUploadBatchSize()).thenReturn(100); - DebuggerContext.ProbeResolver resolver = - (encodedProbeId) -> resolver(encodedProbeId, configuration.getLogProbes()); - currentTransformer = new DebuggerTransformer(config, configuration); + ProbeMetadata probeMetadata = new ProbeMetadata(); + currentTransformer = new DebuggerTransformer(config, probeMetadata, configuration); instr.addTransformer(currentTransformer); TestSnapshotListener listener = new TestSnapshotListener(config, mock(ProbeStatusSink.class)); DebuggerAgentHelper.injectSink(listener); - DebuggerContext.initProbeResolver(resolver); + DebuggerContext.initProbeResolver(probeMetadata::getProbe); DebuggerContext.initClassFilter(new DenyListHelper(null)); DebuggerContext.initValueSerializer(new JsonSnapshotSerializer()); return listener; diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/MetricProbesInstrumentationTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/MetricProbesInstrumentationTest.java index c04f2268b31..7e85d142f35 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/MetricProbesInstrumentationTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/MetricProbesInstrumentationTest.java @@ -1336,7 +1336,11 @@ private MetricForwarderListener installMetricProbes(Configuration configuration) probeStatusSink = mock(ProbeStatusSink.class); currentTransformer = new DebuggerTransformer( - config, configuration, null, new DebuggerSink(config, probeStatusSink)); + config, + configuration, + null, + new ProbeMetadata(), + new DebuggerSink(config, probeStatusSink)); instr.addTransformer(currentTransformer); MetricForwarderListener listener = new MetricForwarderListener(); DebuggerContext.initMetricForwarder(listener); diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/ProbeMetadataTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/ProbeMetadataTest.java new file mode 100644 index 00000000000..5bf1fbfac93 --- /dev/null +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/ProbeMetadataTest.java @@ -0,0 +1,32 @@ +package com.datadog.debugger.agent; + +import static org.junit.jupiter.api.Assertions.*; + +import com.datadog.debugger.probe.LogProbe; +import org.junit.jupiter.api.Test; + +class ProbeMetadataTest { + + @Test + void addProbe() { + ProbeMetadata probeMetadata = new ProbeMetadata(); + probeMetadata.addProbe(LogProbe.builder().probeId("probe-id0", 0).build()); + probeMetadata.addProbe(LogProbe.builder().probeId("probe-id1", 0).build()); + probeMetadata.addProbe(LogProbe.builder().probeId("probe-id2", 0).build()); + assertEquals(3, probeMetadata.size()); + assertEquals("probe-id0", probeMetadata.getProbe(0).getId()); + } + + @Test + void removeProbe() { + ProbeMetadata probeMetadata = new ProbeMetadata(); + probeMetadata.addProbe(LogProbe.builder().probeId("probe-id0", 0).build()); + probeMetadata.addProbe(LogProbe.builder().probeId("probe-id1", 0).build()); + probeMetadata.addProbe(LogProbe.builder().probeId("probe-id2", 0).build()); + probeMetadata.removeProbe(1); + assertEquals(2, probeMetadata.size()); + probeMetadata.removeProbe("probe-id2:0"); + assertEquals(1, probeMetadata.size()); + assertEquals("probe-id0", probeMetadata.getProbe(0).getId()); + } +} diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/SnapshotSerializationTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/SnapshotSerializationTest.java index e82ede446be..3822fcdad02 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/SnapshotSerializationTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/SnapshotSerializationTest.java @@ -124,7 +124,6 @@ public void roundTripCapturedValue() throws IOException, URISyntaxException { context.addLocals( new CapturedContext.CapturedValue[] {normalValuedLocal, normalNullLocal, notCapturedLocal}); context.evaluate( - PROBE_ID.getId(), new ProbeImplementation.NoopProbeImplementation(PROBE_ID, PROBE_LOCATION), String.class.getTypeName(), -1, diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/SpanDecorationProbeInstrumentationTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/SpanDecorationProbeInstrumentationTest.java index e7bab6d9392..f2305d21a34 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/SpanDecorationProbeInstrumentationTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/SpanDecorationProbeInstrumentationTest.java @@ -714,13 +714,14 @@ private void installSpanDecorationProbes(String expectedClassName, Configuration .thenReturn("http://localhost:8126/debugger/v1/input"); when(config.getFinalDebuggerSymDBUrl()).thenReturn("http://localhost:8126/symdb/v1/input"); probeStatusSink = mock(ProbeStatusSink.class); + ProbeMetadata probeMetadata = new ProbeMetadata(); currentTransformer = new DebuggerTransformer( - config, configuration, null, new DebuggerSink(config, probeStatusSink)); + config, configuration, null, probeMetadata, new DebuggerSink(config, probeStatusSink)); instr.addTransformer(currentTransformer); mockSink = new MockSink(config, probeStatusSink); DebuggerAgentHelper.injectSink(mockSink); - DebuggerContext.initProbeResolver((encodedProbeId) -> resolver(encodedProbeId, configuration)); + DebuggerContext.initProbeResolver(probeMetadata::getProbe); DebuggerContext.initClassFilter(new DenyListHelper(null)); } diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/SpanProbeInstrumentationTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/SpanProbeInstrumentationTest.java index 5f3d1e7aabc..ece84ac483c 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/SpanProbeInstrumentationTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/SpanProbeInstrumentationTest.java @@ -147,7 +147,11 @@ private MockTracer installSpanProbes(Configuration configuration) { probeStatusSink = mock(ProbeStatusSink.class); currentTransformer = new DebuggerTransformer( - config, configuration, null, new DebuggerSink(config, probeStatusSink)); + config, + configuration, + null, + new ProbeMetadata(), + new DebuggerSink(config, probeStatusSink)); instr.addTransformer(currentTransformer); mockSink = new MockSink(config, probeStatusSink); DebuggerAgentHelper.injectSink(mockSink); diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/exception/DefaultExceptionDebuggerTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/exception/DefaultExceptionDebuggerTest.java index 0f2487fee39..f4f02e9c7c1 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/exception/DefaultExceptionDebuggerTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/exception/DefaultExceptionDebuggerTest.java @@ -367,12 +367,7 @@ private void evalAndCommitProbe(RuntimeException exception, ExceptionProbe excep exceptionProbe.buildLocation(null); CapturedContext capturedContext = new CapturedContext(); capturedContext.addThrowable(exception); - capturedContext.evaluate( - exceptionProbe.getProbeId().getEncodedId(), - exceptionProbe, - "", - System.currentTimeMillis(), - MethodLocation.EXIT); + capturedContext.evaluate(exceptionProbe, "", System.currentTimeMillis(), MethodLocation.EXIT); exceptionProbe.commit(CapturedContext.EMPTY_CAPTURING_CONTEXT, capturedContext, emptyList()); } diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/exception/ExceptionProbeInstrumentationTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/exception/ExceptionProbeInstrumentationTest.java index 9f55cbdb741..af925cc0009 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/exception/ExceptionProbeInstrumentationTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/exception/ExceptionProbeInstrumentationTest.java @@ -20,6 +20,7 @@ import com.datadog.debugger.agent.DebuggerTransformer; import com.datadog.debugger.agent.JsonSnapshotSerializer; import com.datadog.debugger.agent.MockSampler; +import com.datadog.debugger.agent.ProbeMetadata; import com.datadog.debugger.probe.ExceptionProbe; import com.datadog.debugger.probe.LogProbe; import com.datadog.debugger.probe.ProbeDefinition; @@ -113,6 +114,7 @@ public void after() { instr.removeTransformer(currentTransformer); } ProbeRateLimiter.setSamplerSupplier(null); + ProbeRateLimiter.resetAll(); } @Test @@ -406,9 +408,10 @@ private DebuggerTransformer createTransformer( Config config, Configuration configuration, DebuggerTransformer.InstrumentationListener listener, + ProbeMetadata probeMetadata, DebuggerSink debuggerSink) { DebuggerTransformer debuggerTransformer = - new DebuggerTransformer(config, configuration, listener, debuggerSink); + new DebuggerTransformer(config, configuration, listener, probeMetadata, debuggerSink); currentTransformer = debuggerTransformer; return debuggerTransformer; } diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/probe/LogProbeTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/probe/LogProbeTest.java index 247324b3c1c..968e931cb6d 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/probe/LogProbeTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/probe/LogProbeTest.java @@ -204,11 +204,7 @@ private boolean fillSnapshot(DebugSessionStatus status) { private static CapturedContext capturedContext(AgentSpan span, ProbeDefinition probeDefinition) { CapturedContext context = new CapturedContext(); context.evaluate( - probeDefinition.getProbeId().getEncodedId(), - probeDefinition, - "Log Probe test", - System.currentTimeMillis(), - MethodLocation.DEFAULT); + probeDefinition, "Log Probe test", System.currentTimeMillis(), MethodLocation.DEFAULT); return context; } @@ -287,7 +283,7 @@ private void fillStatus( private LogStatus prepareContext( CapturedContext context, LogProbe logProbe, MethodLocation methodLocation) { - context.evaluate(PROBE_ID.getEncodedId(), logProbe, "", 0, methodLocation); + context.evaluate(logProbe, "", 0, methodLocation); return (LogStatus) context.getStatus(PROBE_ID.getEncodedId()); } diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/trigger/TriggerProbeTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/trigger/TriggerProbeTest.java index 79ad1e25e22..1c5ce04ed86 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/trigger/TriggerProbeTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/trigger/TriggerProbeTest.java @@ -32,6 +32,7 @@ import java.util.Collection; import java.util.List; import org.joor.Reflect; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -56,6 +57,11 @@ public void before() { setFieldInConfig(Config.get(), "distributedDebuggerEnabled", true); } + @AfterEach + public void after() { + ProbeRateLimiter.resetAll(); + } + @Test public void conditions() throws IOException, URISyntaxException { final String className = "com.datadog.debugger.TriggerProbe02"; diff --git a/dd-java-agent/instrumentation-testing/src/main/groovy/datadog/trace/agent/test/InstrumentationSpecification.groovy b/dd-java-agent/instrumentation-testing/src/main/groovy/datadog/trace/agent/test/InstrumentationSpecification.groovy index 2edd984c51b..6da827a1b76 100644 --- a/dd-java-agent/instrumentation-testing/src/main/groovy/datadog/trace/agent/test/InstrumentationSpecification.groovy +++ b/dd-java-agent/instrumentation-testing/src/main/groovy/datadog/trace/agent/test/InstrumentationSpecification.groovy @@ -326,7 +326,7 @@ abstract class InstrumentationSpecification extends DDSpecification implements A INSTRUMENTATION.addTransformer(new DebuggerTransformer(config, configuration, { ProbeDefinition definition, InstrumentationResult result -> - }, sink)) + }, configurationUpdater.getProbeMetadata(), sink)) DebuggerContext.initProbeResolver(configurationUpdater) DebuggerContext.initClassFilter(new DenyListHelper(null)) DebuggerContext.initValueSerializer(new JsonSnapshotSerializer())