Skip to content

Commit 9d160dc

Browse files
committed
Capture values at entry for method probe
method probe when evaluateAt is Exit and no condition should capture entry values. When there is a condition, entry values are not captured instrumentation check the presence of the condition to generate the entry instrumentation or not. therefore, the dummy definition used when duplicate probes need to merge the probe conditions if at least one probe has one condition.
1 parent 866fc61 commit 9d160dc

File tree

3 files changed

+50
-2
lines changed

3 files changed

+50
-2
lines changed

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/DebuggerTransformer.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static java.util.Collections.singletonList;
44
import static java.util.stream.Collectors.toList;
55

6+
import com.datadog.debugger.el.ProbeCondition;
67
import com.datadog.debugger.instrumentation.DiagnosticMessage;
78
import com.datadog.debugger.instrumentation.InstrumentationResult;
89
import com.datadog.debugger.instrumentation.MethodInfo;
@@ -693,6 +694,7 @@ private ProbeDefinition selectReferenceDefinition(
693694
MethodLocation evaluateAt = MethodLocation.EXIT;
694695
LogProbe.Capture capture = null;
695696
boolean captureSnapshot = false;
697+
ProbeCondition probeCondition = null;
696698
Where where = capturedContextProbes.get(0).getWhere();
697699
ProbeId probeId = capturedContextProbes.get(0).getProbeId();
698700
for (ProbeDefinition definition : capturedContextProbes) {
@@ -704,6 +706,10 @@ private ProbeDefinition selectReferenceDefinition(
704706
LogProbe logProbe = (LogProbe) definition;
705707
captureSnapshot = captureSnapshot | logProbe.isCaptureSnapshot();
706708
capture = mergeCapture(capture, logProbe.getCapture());
709+
probeCondition =
710+
probeCondition == null && logProbe.getProbeCondition() != null
711+
? logProbe.getProbeCondition()
712+
: probeCondition;
707713
}
708714
if (definition.getEvaluateAt() == MethodLocation.ENTRY
709715
|| definition.getEvaluateAt() == MethodLocation.DEFAULT) {
@@ -713,6 +719,7 @@ private ProbeDefinition selectReferenceDefinition(
713719
if (hasLogProbe) {
714720
return LogProbe.builder()
715721
.probeId(probeId)
722+
.when(probeCondition)
716723
.where(where)
717724
.evaluateAt(evaluateAt)
718725
.capture(capture)

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/CapturedContextInstrumentor.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import static org.objectweb.asm.Type.VOID_TYPE;
2828
import static org.objectweb.asm.Type.getType;
2929

30+
import com.datadog.debugger.probe.ExceptionProbe;
3031
import com.datadog.debugger.probe.ProbeDefinition;
3132
import com.datadog.debugger.probe.SpanDecorationProbe;
3233
import com.datadog.debugger.probe.Where;
@@ -422,8 +423,11 @@ private void instrumentMethodEnter() {
422423
LabelNode targetNode = new LabelNode();
423424
LabelNode gotoNode = new LabelNode();
424425
insnList.add(new JumpInsnNode(Opcodes.IFEQ, targetNode));
425-
// if evaluation is at exit, skip collecting data at enter
426-
if (definition.getEvaluateAt() != MethodLocation.EXIT) {
426+
// if evaluation is at exit and with condition and not exception probe, skip collecting data at
427+
// enter
428+
if ((definition.getEvaluateAt() != MethodLocation.EXIT
429+
|| !definition.hasCondition())
430+
&& !(definition instanceof ExceptionProbe)) {
427431
LabelNode inProbeStartLabel = new LabelNode();
428432
insnList.add(inProbeStartLabel);
429433
// stack []

dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/CapturedSnapshotTest.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,43 @@ public void methodProbe() throws IOException, URISyntaxException {
134134
assertEquals("CapturedSnapshot01.main", snapshot.getStack().get(0).getFunction());
135135
}
136136

137+
@Test
138+
public void methodProbeAtExit() throws IOException, URISyntaxException {
139+
final String CLASS_NAME = "CapturedSnapshot01";
140+
TestSnapshotListener listener =
141+
installSingleProbeAtExit(CLASS_NAME, "main", "int (java.lang.String)");
142+
Class<?> testClass = compileAndLoadClass(CLASS_NAME);
143+
int result = Reflect.onClass(testClass).call("main", "1").get();
144+
assertEquals(3, result);
145+
Snapshot snapshot = assertOneSnapshot(listener);
146+
assertCaptureArgs(snapshot.getCaptures().getEntry(), "arg", "java.lang.String", "1");
147+
assertCaptureArgs(snapshot.getCaptures().getReturn(), "arg", "java.lang.String", "1");
148+
assertTrue(snapshot.getDuration() > 0);
149+
assertTrue(snapshot.getStack().size() > 0);
150+
assertEquals("CapturedSnapshot01.main", snapshot.getStack().get(0).getFunction());
151+
}
152+
153+
@Test
154+
public void methodProbeAtExitWithCondition() throws IOException, URISyntaxException {
155+
final String CLASS_NAME = "CapturedSnapshot01";
156+
LogProbe probe =
157+
createProbeBuilder(PROBE_ID, CLASS_NAME, "main", "int (java.lang.String)")
158+
.when(
159+
new ProbeCondition(DSL.when(DSL.eq(DSL.ref("arg"), DSL.value("1"))), "arg == '1'"))
160+
.evaluateAt(MethodLocation.EXIT)
161+
.build();
162+
TestSnapshotListener listener = installProbes(probe);
163+
Class<?> testClass = compileAndLoadClass(CLASS_NAME);
164+
int result = Reflect.onClass(testClass).call("main", "1").get();
165+
assertEquals(3, result);
166+
Snapshot snapshot = assertOneSnapshot(listener);
167+
assertEquals(CapturedContext.EMPTY_CAPTURING_CONTEXT, snapshot.getCaptures().getEntry());
168+
assertCaptureArgs(snapshot.getCaptures().getReturn(), "arg", "java.lang.String", "1");
169+
assertTrue(snapshot.getDuration() > 0);
170+
assertTrue(snapshot.getStack().size() > 0);
171+
assertEquals("CapturedSnapshot01.main", snapshot.getStack().get(0).getFunction());
172+
}
173+
137174
@Test
138175
public void localVarHoistingNoPreviousStore() throws IOException, URISyntaxException {
139176
final String CLASS_NAME = "com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper";

0 commit comments

Comments
 (0)