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

This commit is contained in:
Rafael Winterhalter 2019-04-28 19:10:21 +02:00
parent 69e8aab4b1
commit eeaa27af83
3 changed files with 34 additions and 9 deletions

View File

@ -1,6 +1,7 @@
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;
}

View File

@ -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(

View File

@ -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,