fix Transformer do not register problem, when Enhancer error. #1184

pull/1413/head
hengyunabc 5 years ago
parent 21365c7237
commit f66e1c9d59

@ -66,9 +66,10 @@ public class Enhancer implements ClassFileTransformer {
private final AdviceListener listener;
private final boolean isTracing;
private final boolean skipJDKTrace;
private final Set<Class<?>> matchingClasses;
private final Matcher classNameMatcher;
private final Matcher methodNameMatcher;
private final EnhancerAffect affect;
private Set<Class<?>> matchingClasses = null;
// 被增强的类的缓存
private final static Map<Class<?>/* Class */, Object> classBytesCache = new WeakHashMap<Class<?>, Object>();
@ -86,14 +87,14 @@ public class Enhancer implements ClassFileTransformer {
* @param methodNameMatcher
* @param affect
*/
Enhancer(AdviceListener listener, boolean isTracing, boolean skipJDKTrace, Set<Class<?>> 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<Class<?>> 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);

@ -66,6 +66,8 @@ public class TransformerManager {
}
public void destroy() {
watchTransformers.clear();
traceTransformers.clear();
instrumentation.removeTransformer(classFileTransformer);
}

@ -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");
}

@ -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();
}
}

Loading…
Cancel
Save