Set max stack size in bytebuddy exception handler

This commit is contained in:
Andrew Kent 2018-03-07 13:04:42 -05:00
parent 22aa2d770f
commit 5ffd2142e9
5 changed files with 39 additions and 3 deletions

View File

@ -3,7 +3,6 @@ package datadog.trace.agent.tooling;
import datadog.trace.agent.bootstrap.ExceptionLogger; import datadog.trace.agent.bootstrap.ExceptionLogger;
import net.bytebuddy.implementation.Implementation; import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.bytecode.StackManipulation; import net.bytebuddy.implementation.bytecode.StackManipulation;
import net.bytebuddy.implementation.bytecode.StackSize;
import net.bytebuddy.jar.asm.Label; import net.bytebuddy.jar.asm.Label;
import net.bytebuddy.jar.asm.MethodVisitor; import net.bytebuddy.jar.asm.MethodVisitor;
import net.bytebuddy.jar.asm.Opcodes; import net.bytebuddy.jar.asm.Opcodes;
@ -19,7 +18,8 @@ public class ExceptionHandlers {
private static final StackManipulation EXCEPTION_STACK_HANDLER = private static final StackManipulation EXCEPTION_STACK_HANDLER =
new StackManipulation() { new StackManipulation() {
private final Size size = StackSize.SINGLE.toDecreasingSize(); // Pops one Throwable off the stack. Maxes the stack to at least 3.
private final Size size = new StackManipulation.Size(-1, 3);
@Override @Override
public boolean isValid() { public boolean isValid() {

View File

@ -33,6 +33,13 @@ class ExceptionHandlerTest extends Specification {
.advice( .advice(
isMethod().and(named("isInstrumented")), isMethod().and(named("isInstrumented")),
BadAdvice.getName())) BadAdvice.getName()))
.transform(
new AgentBuilder.Transformer.ForAdvice()
.with(new AgentBuilder.LocationStrategy.Simple(ClassFileLocator.ForClassLoader.of(BadAdvice.getClassLoader())))
.withExceptionHandler(ExceptionHandlers.defaultExceptionHandler())
.advice(
isMethod().and(named("smallStack").or(named("largeStack"))),
BadAdvice.NoOpAdvice.getName()))
.asDecorator() .asDecorator()
ByteBuddyAgent.install() ByteBuddyAgent.install()
@ -80,9 +87,31 @@ class ExceptionHandlerTest extends Specification {
testAppender.list.size() == initLogEvents testAppender.list.size() == initLogEvents
} }
def "exception handler sets the correct stack size"() {
when:
SomeClass.smallStack()
SomeClass.largeStack()
then:
noExceptionThrown()
}
static class SomeClass { static class SomeClass {
static boolean isInstrumented() { static boolean isInstrumented() {
return false return false
} }
static void smallStack() {
// a method with a max stack of 0
}
static void largeStack() {
// a method with a max stack of 6
long l = 22l
int i = 3
double d = 32.2d
Object o = new Object()
println "large stack: $l $i $d $o"
}
} }
} }

View File

@ -8,4 +8,11 @@ public class BadAdvice {
returnVal = true; returnVal = true;
throw new RuntimeException("Test Exception"); throw new RuntimeException("Test Exception");
} }
public static class NoOpAdvice {
@Advice.OnMethodExit(suppress = Throwable.class)
public static void doNothing() {
System.currentTimeMillis();
}
}
} }

View File

@ -7,7 +7,7 @@ import spock.lang.Timeout
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@Timeout(1) @Timeout(10)
class DDSpanTest extends Specification { class DDSpanTest extends Specification {
def writer = new ListWriter() def writer = new ListWriter()
def tracer = new DDTracer(writer) def tracer = new DDTracer(writer)