Fixes Only add frames if class file version supports attribute
MODIFY
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/ExceptionHandlers.java
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/ExceptionHandlers.java
package datadog.trace.agent.tooling;
import datadog.trace.bootstrap.ExceptionLogger;
+import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.asm.Advice.ExceptionHandler;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.bytecode.StackManipulation;
@@ -41,6 +42,9 @@ public class ExceptionHandlers {
final Label eatException = new Label();
final Label handlerExit = new Label();
+ // Frames are only meaningful for class files in version 6 or later.
+ final boolean frames = context.getClassFileVersion().isAtLeast(ClassFileVersion.JAVA_V6);
+
mv.visitTryCatchBlock(logStart, logEnd, eatException, "java/lang/Throwable");
// stack: (top) throwable
@@ -67,13 +71,17 @@ public class ExceptionHandlers {
// if the runtime can't reach our ExceptionHandler or logger,
// silently eat the exception
mv.visitLabel(eatException);
+ if (frames) {
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ }
mv.visitInsn(Opcodes.POP);
// mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable",
// "printStackTrace", "()V", false);
mv.visitLabel(handlerExit);
+ if (frames) {
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ }
return size;
}

MODIFY
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/context/FieldBackedProvider.java
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/context/FieldBackedProvider.java
@@ -25,6 +25,7 @@ import java.util.Map;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.ByteBuddy;
+import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.description.field.FieldDescription;
@@ -620,6 +621,7 @@ public class FieldBackedProvider implements InstrumentationContextProvider {
getFieldAccessorInterface(keyClassName, contextClassName);
private final String accessorInterfaceInternalName = accessorInterface.getInternalName();
private final String instrumentedTypeInternalName = instrumentedType.getInternalName();
+ private final boolean frames = implementationContext.getClassFileVersion().isAtLeast(ClassFileVersion.JAVA_V6);
@Override
public MethodVisitor visitMethod(
@@ -679,7 +681,9 @@ public class FieldBackedProvider implements InstrumentationContextProvider {
true);
mv.visitInsn(Opcodes.ARETURN);
mv.visitLabel(elseLabel);
+ if (frames) {
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ }
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitVarInsn(Opcodes.ALOAD, 1);
mv.visitMethodInsn(
@@ -732,7 +736,9 @@ public class FieldBackedProvider implements InstrumentationContextProvider {
true);
mv.visitJumpInsn(Opcodes.GOTO, endLabel);
mv.visitLabel(elseLabel);
+ if (frames) {
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ }
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitVarInsn(Opcodes.ALOAD, 1);
mv.visitVarInsn(Opcodes.ALOAD, 2);
@@ -743,7 +749,9 @@ public class FieldBackedProvider implements InstrumentationContextProvider {
Utils.getMethodDefinition(instrumentedType, "mapPut").getDescriptor(),
false);
mv.visitLabel(endLabel);
+ if (frames) {
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ }
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
@@ -778,7 +786,9 @@ public class FieldBackedProvider implements InstrumentationContextProvider {
mv.visitVarInsn(Opcodes.ALOAD, 1);
mv.visitInsn(Opcodes.ARETURN);
mv.visitLabel(elseLabel);
+ if (frames) {
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ }
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitVarInsn(Opcodes.ALOAD, 1);
mv.visitMethodInsn(

MODIFY
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/muzzle/MuzzleVisitor.java
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/muzzle/MuzzleVisitor.java
@@ -6,6 +6,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.field.FieldList;
@@ -46,15 +47,19 @@ public class MuzzleVisitor implements AsmVisitorWrapper {
MethodList<?> methods,
int writerFlags,
int readerFlags) {
- return new InsertSafetyMatcher(classVisitor);
+ return new InsertSafetyMatcher(classVisitor, implementationContext.getClassFileVersion().isAtLeast(ClassFileVersion.JAVA_V6));
}
public static class InsertSafetyMatcher extends ClassVisitor {
+
+ private final boolean frames;
+
private String instrumentationClassName;
private Instrumenter.Default instrumenter;
- public InsertSafetyMatcher(ClassVisitor classVisitor) {
+ public InsertSafetyMatcher(ClassVisitor classVisitor, boolean frames) {
super(Opcodes.ASM7, classVisitor);
+ this.frames = frames;
}
@Override
@@ -430,7 +435,9 @@ public class MuzzleVisitor implements AsmVisitorWrapper {
"Ldatadog/trace/agent/tooling/muzzle/ReferenceMatcher;");
mv.visitLabel(ret);
+ if (frames) {
mv.visitFrame(Opcodes.F_SAME, 1, null, 0, null);
+ }
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitFieldInsn(
Opcodes.GETFIELD,

Fixes #813: Only add frames if class file version supports attribute