diff --git a/core/src/main/java/com/taobao/arthas/core/advisor/Enhancer.java b/core/src/main/java/com/taobao/arthas/core/advisor/Enhancer.java index 431073b0e..518a341f5 100644 --- a/core/src/main/java/com/taobao/arthas/core/advisor/Enhancer.java +++ b/core/src/main/java/com/taobao/arthas/core/advisor/Enhancer.java @@ -66,9 +66,10 @@ public class Enhancer implements ClassFileTransformer { private final AdviceListener listener; private final boolean isTracing; private final boolean skipJDKTrace; - private final Set> matchingClasses; + private final Matcher classNameMatcher; private final Matcher methodNameMatcher; private final EnhancerAffect affect; + private Set> matchingClasses = null; // 被增强的类的缓存 private final static Map/* Class */, Object> classBytesCache = new WeakHashMap, Object>(); @@ -86,14 +87,14 @@ public class Enhancer implements ClassFileTransformer { * @param methodNameMatcher 方法名匹配 * @param affect 影响统计 */ - Enhancer(AdviceListener listener, boolean isTracing, boolean skipJDKTrace, Set> matchingClasses, - Matcher methodNameMatcher, EnhancerAffect affect) { + public Enhancer(AdviceListener listener, boolean isTracing, boolean skipJDKTrace, Matcher classNameMatcher, + Matcher methodNameMatcher) { this.listener = listener; this.isTracing = isTracing; this.skipJDKTrace = skipJDKTrace; - this.matchingClasses = matchingClasses; + this.classNameMatcher = classNameMatcher; this.methodNameMatcher = methodNameMatcher; - this.affect = affect; + this.affect = new EnhancerAffect();; } public static class SpyInterceptor { @@ -352,6 +353,9 @@ public class Enhancer implements ClassFileTransformer { try { FileUtils.writeByteArrayToFile(dumpClassFile, data); affect.addClassDumpFile(dumpClassFile); + if (GlobalOptions.verbose) { + logger.info("dump enhanced class: {}, path: {}", className, dumpClassFile); + } } catch (IOException e) { logger.warn("dump class:{} to file {} failed.", className, dumpClassFile, e); } @@ -407,41 +411,33 @@ public class Enhancer implements ClassFileTransformer { * @return 增强影响范围 * @throws UnmodifiableClassException 增强失败 */ - public static synchronized EnhancerAffect enhance(final Instrumentation inst, final AdviceListener listener, - final boolean isTracing, final boolean skipJDKTrace, final Matcher classNameMatcher, - final Matcher methodNameMatcher) throws UnmodifiableClassException { - - final EnhancerAffect affect = new EnhancerAffect(); - + public synchronized EnhancerAffect enhance(final Instrumentation inst) throws UnmodifiableClassException { // 获取需要增强的类集合 - final Set> enhanceClassSet = GlobalOptions.isDisableSubClass + this.matchingClasses = GlobalOptions.isDisableSubClass ? SearchUtils.searchClass(inst, classNameMatcher) : SearchUtils.searchSubClass(inst, SearchUtils.searchClass(inst, classNameMatcher)); // 过滤掉无法被增强的类 - filter(enhanceClassSet); + filter(matchingClasses); - // 构建增强器 - final Enhancer enhancer = new Enhancer(listener, isTracing, skipJDKTrace, enhanceClassSet, methodNameMatcher, - affect); - affect.setTransformer(enhancer); + affect.setTransformer(this); try { - ArthasBootstrap.getInstance().getTransformerManager().addTransformer(enhancer, isTracing); + ArthasBootstrap.getInstance().getTransformerManager().addTransformer(this, isTracing); //inst.addTransformer(enhancer, true); // 批量增强 if (GlobalOptions.isBatchReTransform) { - final int size = enhanceClassSet.size(); + final int size = matchingClasses.size(); final Class[] classArray = new Class[size]; - arraycopy(enhanceClassSet.toArray(), 0, classArray, 0, size); + arraycopy(matchingClasses.toArray(), 0, classArray, 0, size); if (classArray.length > 0) { inst.retransformClasses(classArray); logger.info("Success to batch transform classes: " + Arrays.toString(classArray)); } } else { // for each 增强 - for (Class clazz : enhanceClassSet) { + for (Class clazz : matchingClasses) { try { inst.retransformClasses(clazz); logger.info("Success to transform class: " + clazz); diff --git a/core/src/main/java/com/taobao/arthas/core/advisor/TransformerManager.java b/core/src/main/java/com/taobao/arthas/core/advisor/TransformerManager.java index 492cfb085..08b7fe15a 100644 --- a/core/src/main/java/com/taobao/arthas/core/advisor/TransformerManager.java +++ b/core/src/main/java/com/taobao/arthas/core/advisor/TransformerManager.java @@ -66,6 +66,8 @@ public class TransformerManager { } public void destroy() { + watchTransformers.clear(); + traceTransformers.clear(); instrumentation.removeTransformer(classFileTransformer); } diff --git a/core/src/main/java/com/taobao/arthas/core/command/monitor200/EnhancerCommand.java b/core/src/main/java/com/taobao/arthas/core/command/monitor200/EnhancerCommand.java index f3af694f2..b2de2d3fe 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/monitor200/EnhancerCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/monitor200/EnhancerCommand.java @@ -1,6 +1,5 @@ package com.taobao.arthas.core.command.monitor200; -import java.arthas.SpyAPI; import java.lang.instrument.Instrumentation; import java.lang.instrument.UnmodifiableClassException; import java.util.Collections; @@ -8,10 +7,6 @@ import java.util.List; import com.alibaba.arthas.deps.org.slf4j.Logger; import com.alibaba.arthas.deps.org.slf4j.LoggerFactory; -import com.taobao.arthas.bytekit.asm.binding.Binding; -import com.taobao.arthas.bytekit.asm.interceptor.annotation.AtEnter; -import com.taobao.arthas.bytekit.asm.interceptor.annotation.AtExceptionExit; -import com.taobao.arthas.bytekit.asm.interceptor.annotation.AtExit; import com.taobao.arthas.core.advisor.AdviceListener; import com.taobao.arthas.core.advisor.Enhancer; import com.taobao.arthas.core.advisor.InvokeTraceable; @@ -114,8 +109,10 @@ public abstract class EnhancerCommand extends AnnotatedCommand { skipJDKTrace = ((AbstractTraceAdviceListener) listener).getCommand().isSkipJDKTrace(); } - EnhancerAffect effect = Enhancer.enhance(inst, listener, listener instanceof InvokeTraceable, - skipJDKTrace, getClassNameMatcher(), getMethodNameMatcher()); + Enhancer enhancer = new Enhancer(listener, listener instanceof InvokeTraceable, skipJDKTrace, getClassNameMatcher(), getMethodNameMatcher()); + // 注册通知监听器 + process.register(lock, listener, enhancer); + EnhancerAffect effect = enhancer.enhance(inst); if (effect.cCnt() == 0 || effect.mCnt() == 0) { // no class effected @@ -132,8 +129,6 @@ public abstract class EnhancerCommand extends AnnotatedCommand { // 这里做个补偿,如果在enhance期间,unLock被调用了,则补偿性放弃 if (session.getLock() == lock) { - // 注册通知监听器 - process.register(lock, listener, effect.getTransformer()); if (process.isForeground()) { process.echoTips(Constants.Q_OR_CTRL_C_ABORT_MSG + "\n"); } diff --git a/core/src/main/java/com/taobao/arthas/core/shell/system/impl/GlobalJobControllerImpl.java b/core/src/main/java/com/taobao/arthas/core/shell/system/impl/GlobalJobControllerImpl.java index f0900800a..938f4e4f2 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/system/impl/GlobalJobControllerImpl.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/system/impl/GlobalJobControllerImpl.java @@ -109,8 +109,9 @@ public class GlobalJobControllerImpl extends JobControllerImpl { @Override public void run() { if (job != null) { - job.terminate(); + Job temp = job; job = null; + temp.terminate(); } }