Fix class loading instrumentation on IBM JVM (#169)

This commit is contained in:
Trask Stalnaker 2020-02-18 11:42:00 -08:00 committed by GitHub
parent 3632e3bb2d
commit 0a3afc362f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 20 additions and 6 deletions

View File

@ -12,6 +12,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService;
import io.opentelemetry.auto.bootstrap.CallDepthThreadLocalMap;
import io.opentelemetry.auto.tooling.Constants;
import io.opentelemetry.auto.tooling.Instrumenter;
import java.util.Map;
@ -38,8 +39,10 @@ public final class ClassloadingInstrumentation extends Instrumenter.Default {
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
// safe to exclude java.lang.ClassLoader since its loadClass() delegates
// just an optimization to exclude common class loaders that are known to delegate to the
// bootstrap loader (or happen to _be_ the bootstrap loader)
return not(named("java.lang.ClassLoader"))
.and(not(named("com.ibm.oti.vm.BootstrapClassLoader")))
.and(not(named("io.opentelemetry.auto.bootstrap.AgentClassLoader")))
.and(safeHasSuperType(named("java.lang.ClassLoader")));
}
@ -68,7 +71,12 @@ public final class ClassloadingInstrumentation extends Instrumenter.Default {
public static class LoadClassAdvice {
@Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)
public static Class<?> onEnter(@Advice.Argument(0) final String name) {
public static Class<?> onEnter(
@Advice.Argument(0) final String name, @Advice.Local("_callDepth") int callDepth) {
callDepth = CallDepthThreadLocalMap.incrementCallDepth(ClassLoader.class);
if (callDepth > 0) {
return null;
}
for (final String prefix : Constants.BOOTSTRAP_PACKAGE_PREFIXES) {
if (name.startsWith(prefix)) {
try {
@ -80,11 +88,17 @@ public final class ClassloadingInstrumentation extends Instrumenter.Default {
return null;
}
@Advice.OnMethodExit
@Advice.OnMethodExit(onThrowable = Throwable.class)
public static void onExit(
@Advice.Return(readOnly = false) Class<?> result, @Advice.Enter final Class<?> clazz) {
if (clazz != null) {
result = clazz;
@Advice.Local("_callDepth") final int callDepth,
@Advice.Return(readOnly = false) Class<?> result,
@Advice.Enter final Class<?> resultFromBootstrapLoader) {
if (callDepth > 0) {
return;
}
CallDepthThreadLocalMap.reset(ClassLoader.class);
if (resultFromBootstrapLoader != null) {
result = resultFromBootstrapLoader;
}
}
}