exclude box/unbox method when trace method

This commit is contained in:
hengyunabc 2020-05-19 16:26:52 +08:00
parent 2b740b121f
commit f39236eb86

View File

@ -47,6 +47,8 @@ import com.taobao.arthas.bytekit.asm.location.filter.LocationFilter;
import com.taobao.arthas.bytekit.utils.AsmUtils; import com.taobao.arthas.bytekit.utils.AsmUtils;
import com.taobao.arthas.core.GlobalOptions; import com.taobao.arthas.core.GlobalOptions;
import com.taobao.arthas.core.bytecode.AdviceListenerManager; import com.taobao.arthas.core.bytecode.AdviceListenerManager;
import com.taobao.arthas.core.bytecode.SpyImpl;
import com.taobao.arthas.core.server.ArthasBootstrap;
import com.taobao.arthas.core.util.ArthasCheckUtils; import com.taobao.arthas.core.util.ArthasCheckUtils;
import com.taobao.arthas.core.util.FileUtils; import com.taobao.arthas.core.util.FileUtils;
import com.taobao.arthas.core.util.SearchUtils; import com.taobao.arthas.core.util.SearchUtils;
@ -55,6 +57,7 @@ import com.taobao.arthas.core.util.matcher.Matcher;
/** /**
* 对类进行通知增强 Created by vlinux on 15/5/17. * 对类进行通知增强 Created by vlinux on 15/5/17.
* @author hengyunabc
*/ */
public class Enhancer implements ClassFileTransformer { public class Enhancer implements ClassFileTransformer {
@ -69,6 +72,11 @@ public class Enhancer implements ClassFileTransformer {
// -字节码缓存 // -字节码缓存
private final static Map<Class<?>/* Class */, byte[]/* bytes of Class */> classBytesCache = new WeakHashMap<Class<?>, byte[]>(); private final static Map<Class<?>/* Class */, byte[]/* bytes of Class */> classBytesCache = new WeakHashMap<Class<?>, byte[]>();
private static SpyImpl spyImpl = new SpyImpl();
static {
SpyAPI.setSpy(spyImpl);
}
/** /**
* @param adviceId 通知编号 * @param adviceId 通知编号
@ -78,7 +86,7 @@ public class Enhancer implements ClassFileTransformer {
* @param methodNameMatcher 方法名匹配 * @param methodNameMatcher 方法名匹配
* @param affect 影响统计 * @param affect 影响统计
*/ */
private Enhancer(AdviceListener listener, boolean isTracing, boolean skipJDKTrace, Set<Class<?>> matchingClasses, Enhancer(AdviceListener listener, boolean isTracing, boolean skipJDKTrace, Set<Class<?>> matchingClasses,
Matcher methodNameMatcher, EnhancerAffect affect) { Matcher methodNameMatcher, EnhancerAffect affect) {
this.listener = listener; this.listener = listener;
this.isTracing = isTracing; this.isTracing = isTracing;
@ -131,27 +139,46 @@ public class Enhancer implements ClassFileTransformer {
} }
public static class SpyTraceInterceptor { public static class SpyTraceInterceptor {
@AtInvoke(name = "", inline = true, whenComplete = false, excludes = "java.arthas.SpyAPI") @AtInvoke(name = "", inline = true, whenComplete = false, excludes = {"java.arthas.SpyAPI", "java.lang.Byte"
, "java.lang.Boolean"
, "java.lang.Short"
, "java.lang.Character"
, "java.lang.Integer"
, "java.lang.Float"
, "java.lang.Long"
, "java.lang.Double"})
public static void onInvoke(@Binding.This Object target, @Binding.Class Class<?> clazz, public static void onInvoke(@Binding.This Object target, @Binding.Class Class<?> clazz,
@Binding.InvokeInfo String invokeInfo) { @Binding.InvokeInfo String invokeInfo) {
SpyAPI.atBeforeInvoke(clazz, invokeInfo, target); SpyAPI.atBeforeInvoke(clazz, invokeInfo, target);
} }
@AtInvoke(name = "", inline = true, whenComplete = true, excludes = "java.arthas.SpyAPI") @AtInvoke(name = "", inline = true, whenComplete = true, excludes = {"java.arthas.SpyAPI", "java.lang.Byte"
, "java.lang.Boolean"
, "java.lang.Short"
, "java.lang.Character"
, "java.lang.Integer"
, "java.lang.Float"
, "java.lang.Long"
, "java.lang.Double"})
public static void onInvokeAfter(@Binding.This Object target, @Binding.Class Class<?> clazz, public static void onInvokeAfter(@Binding.This Object target, @Binding.Class Class<?> clazz,
@Binding.InvokeInfo String invokeInfo) { @Binding.InvokeInfo String invokeInfo) {
SpyAPI.atAfterInvoke(clazz, invokeInfo, target); SpyAPI.atAfterInvoke(clazz, invokeInfo, target);
} }
@AtInvokeException(name = "", inline = true, excludes = "java.arthas.SpyAPI") @AtInvokeException(name = "", inline = true, excludes = {"java.arthas.SpyAPI", "java.lang.Byte"
, "java.lang.Boolean"
, "java.lang.Short"
, "java.lang.Character"
, "java.lang.Integer"
, "java.lang.Float"
, "java.lang.Long"
, "java.lang.Double"})
public static void onInvokeException(@Binding.This Object target, @Binding.Class Class<?> clazz, public static void onInvokeException(@Binding.This Object target, @Binding.Class Class<?> clazz,
@Binding.InvokeInfo String invokeInfo, @Binding.Throwable Throwable throwable) { @Binding.InvokeInfo String invokeInfo, @Binding.Throwable Throwable throwable) {
SpyAPI.atInvokeException(clazz, invokeInfo, target, throwable); SpyAPI.atInvokeException(clazz, invokeInfo, target, throwable);
} }
} }
com.taobao.arthas.core.bytecode.SpyImpl spyImpl = new com.taobao.arthas.core.bytecode.SpyImpl();
@Override @Override
public byte[] transform(final ClassLoader inClassLoader, String className, Class<?> classBeingRedefined, public byte[] transform(final ClassLoader inClassLoader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
@ -162,23 +189,14 @@ public class Enhancer implements ClassFileTransformer {
return null; return null;
} }
ClassNode classNode;
SpyAPI.setSpy(spyImpl);
// 首先先检查是否在缓存中存在Class字节码 // 首先先检查是否在缓存中存在Class字节码
// 因为要支持多人协作,存在多人同时增强的情况 // 因为要支持多人协作,存在多人同时增强的情况
// final byte[] byteOfClassInCache = classBytesCache.get(classBeingRedefined); final byte[] byteOfClassInCache = classBytesCache.get(classBeingRedefined);
// if (null != byteOfClassInCache) { if (null != byteOfClassInCache) {
// classNode = AsmUtils.toClassNode(byteOfClassInCache); classfileBuffer = byteOfClassInCache;
// } }
//
// // 如果没有命中缓存,则从原始字节码开始增强
// else {
// classNode = AsmUtils.toClassNode(classfileBuffer);
// }
classNode = AsmUtils.toClassNode(classfileBuffer); ClassNode classNode = AsmUtils.toClassNode(classfileBuffer);
// 生成增强字节码 // 生成增强字节码
DefaultInterceptorClassParser defaultInterceptorClassParser = new DefaultInterceptorClassParser(); DefaultInterceptorClassParser defaultInterceptorClassParser = new DefaultInterceptorClassParser();
@ -380,8 +398,11 @@ public class Enhancer implements ClassFileTransformer {
// 构建增强器 // 构建增强器
final Enhancer enhancer = new Enhancer(listener, isTracing, skipJDKTrace, enhanceClassSet, methodNameMatcher, final Enhancer enhancer = new Enhancer(listener, isTracing, skipJDKTrace, enhanceClassSet, methodNameMatcher,
affect); affect);
affect.setTransformer(enhancer);
try { try {
inst.addTransformer(enhancer, true); ArthasBootstrap.getInstance().getTransformerManager().addTransformer(enhancer, isTracing);
//inst.addTransformer(enhancer, true);
// 批量增强 // 批量增强
if (GlobalOptions.isBatchReTransform) { if (GlobalOptions.isBatchReTransform) {
@ -411,7 +432,7 @@ public class Enhancer implements ClassFileTransformer {
} }
} }
} finally { } finally {
inst.removeTransformer(enhancer); //inst.removeTransformer(enhancer);
} }
return affect; return affect;