mirror of
https://github.com/alibaba/arthas.git
synced 2024-04-21 10:21:39 +00:00
fix Transformer do not register problem, when Enhancer error. #1184
This commit is contained in:
@@ -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");
|
||||
}
|
||||
|
||||
+2
-1
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user