diff --git a/core/src/main/java/com/taobao/arthas/core/advisor/AdviceListener.java b/core/src/main/java/com/taobao/arthas/core/advisor/AdviceListener.java
index bcfefee0e..fa7511b19 100644
--- a/core/src/main/java/com/taobao/arthas/core/advisor/AdviceListener.java
+++ b/core/src/main/java/com/taobao/arthas/core/advisor/AdviceListener.java
@@ -6,6 +6,8 @@ package com.taobao.arthas.core.advisor;
*/
public interface AdviceListener {
+ long id();
+
/**
* 监听器创建
* 监听器被注册时触发
diff --git a/core/src/main/java/com/taobao/arthas/core/advisor/AdviceListenerAdapter.java b/core/src/main/java/com/taobao/arthas/core/advisor/AdviceListenerAdapter.java
index cf1012e55..21315bac3 100644
--- a/core/src/main/java/com/taobao/arthas/core/advisor/AdviceListenerAdapter.java
+++ b/core/src/main/java/com/taobao/arthas/core/advisor/AdviceListenerAdapter.java
@@ -1,5 +1,7 @@
package com.taobao.arthas.core.advisor;
+import java.util.concurrent.atomic.AtomicLong;
+
import com.taobao.arthas.core.command.express.ExpressException;
import com.taobao.arthas.core.command.express.ExpressFactory;
import com.taobao.arthas.core.shell.command.CommandProcess;
@@ -14,7 +16,14 @@ import com.taobao.arthas.core.util.StringUtils;
*
*/
public abstract class AdviceListenerAdapter implements AdviceListener, ProcessAware {
+ private static final AtomicLong ID_GENERATOR = new AtomicLong(0);
private Process process;
+ private long id = ID_GENERATOR.addAndGet(1);
+
+ @Override
+ public long id() {
+ return id;
+ }
@Override
public void create() {
diff --git a/core/src/main/java/com/taobao/arthas/core/advisor/AdviceWeaver.java b/core/src/main/java/com/taobao/arthas/core/advisor/AdviceWeaver.java
index 2b607da6f..aadcbca68 100644
--- a/core/src/main/java/com/taobao/arthas/core/advisor/AdviceWeaver.java
+++ b/core/src/main/java/com/taobao/arthas/core/advisor/AdviceWeaver.java
@@ -19,8 +19,8 @@ public class AdviceWeaver {
private static final Logger logger = LoggerFactory.getLogger(AdviceWeaver.class);
// 通知监听器集合
- private final static Map advices
- = new ConcurrentHashMap();
+ private final static Map advices
+ = new ConcurrentHashMap();
/**
* 注册监听器
@@ -28,13 +28,13 @@ public class AdviceWeaver {
* @param adviceId 通知ID
* @param listener 通知监听器
*/
- public static void reg(int adviceId, AdviceListener listener) {
+ public static void reg(AdviceListener listener) {
// 触发监听器创建
listener.create();
// 注册监听器
- advices.put(adviceId, listener);
+ advices.put(listener.id(), listener);
}
/**
@@ -42,28 +42,28 @@ public class AdviceWeaver {
*
* @param adviceId 通知ID
*/
- public static void unReg(int adviceId) {
-
- // 注销监听器
- final AdviceListener listener = advices.remove(adviceId);
-
- // 触发监听器销毁
+ public static void unReg(AdviceListener listener) {
if (null != listener) {
+ // 注销监听器
+ advices.remove(listener.id());
+
+ // 触发监听器销毁
listener.destroy();
}
-
}
+ public static AdviceListener listener(long id) {
+ return advices.get(id);
+ }
/**
* 恢复监听
*
- * @param adviceId 通知ID
* @param listener 通知监听器
*/
- public static void resume(int adviceId, AdviceListener listener) {
+ public static void resume(AdviceListener listener) {
// 注册监听器
- advices.put(adviceId, listener);
+ advices.put(listener.id(), listener);
}
/**
@@ -71,7 +71,7 @@ public class AdviceWeaver {
*
* @param adviceId 通知ID
*/
- public static AdviceListener suspend(int adviceId) {
+ public static AdviceListener suspend(long adviceId) {
// 注销监听器
return advices.remove(adviceId);
}
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 57fbdee98..8e97bc17e 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
@@ -94,7 +94,8 @@ public class Enhancer implements ClassFileTransformer {
this.skipJDKTrace = skipJDKTrace;
this.classNameMatcher = classNameMatcher;
this.methodNameMatcher = methodNameMatcher;
- this.affect = new EnhancerAffect();;
+ this.affect = new EnhancerAffect();
+ affect.setListenerId(listener.id());
}
public static class SpyInterceptor {
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 b2de2d3fe..2b88f69de 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
@@ -8,6 +8,7 @@ import java.util.List;
import com.alibaba.arthas.deps.org.slf4j.Logger;
import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
import com.taobao.arthas.core.advisor.AdviceListener;
+import com.taobao.arthas.core.advisor.AdviceWeaver;
import com.taobao.arthas.core.advisor.Enhancer;
import com.taobao.arthas.core.advisor.InvokeTraceable;
import com.taobao.arthas.core.shell.cli.Completion;
@@ -21,6 +22,8 @@ import com.taobao.arthas.core.util.Constants;
import com.taobao.arthas.core.util.LogUtil;
import com.taobao.arthas.core.util.affect.EnhancerAffect;
import com.taobao.arthas.core.util.matcher.Matcher;
+import com.taobao.middleware.cli.annotations.Description;
+import com.taobao.middleware.cli.annotations.Option;
/**
* @author beiwei30 on 29/11/2016.
@@ -35,6 +38,14 @@ public abstract class EnhancerCommand extends AnnotatedCommand {
protected Matcher classNameMatcher;
protected Matcher methodNameMatcher;
+ protected long listenerId;
+
+ @Option(longName = "listenerId")
+ @Description("The special listenerId")
+ public void setListenerId(long listenerId) {
+ this.listenerId = listenerId;
+ }
+
/**
* 类名匹配
*
@@ -56,6 +67,15 @@ public abstract class EnhancerCommand extends AnnotatedCommand {
*/
protected abstract AdviceListener getAdviceListener(CommandProcess process);
+ AdviceListener getAdviceListenerWithId(CommandProcess process) {
+ if (listenerId != 0) {
+ AdviceListener listener = AdviceWeaver.listener(listenerId);
+ if (listener != null) {
+ return listener;
+ }
+ }
+ return getAdviceListener(process);
+ }
@Override
public void process(final CommandProcess process) {
// ctrl-C support
@@ -99,7 +119,7 @@ public abstract class EnhancerCommand extends AnnotatedCommand {
int lock = session.getLock();
try {
Instrumentation inst = session.getInstrumentation();
- AdviceListener listener = getAdviceListener(process);
+ AdviceListener listener = getAdviceListenerWithId(process);
if (listener == null) {
warn(process, "advice listener is null");
return;
@@ -111,7 +131,7 @@ public abstract class EnhancerCommand extends AnnotatedCommand {
Enhancer enhancer = new Enhancer(listener, listener instanceof InvokeTraceable, skipJDKTrace, getClassNameMatcher(), getMethodNameMatcher());
// 注册通知监听器
- process.register(lock, listener, enhancer);
+ process.register(listener, enhancer);
EnhancerAffect effect = enhancer.enhance(inst);
if (effect.cCnt() == 0 || effect.mCnt() == 0) {
diff --git a/core/src/main/java/com/taobao/arthas/core/command/monitor200/WatchCommand.java b/core/src/main/java/com/taobao/arthas/core/command/monitor200/WatchCommand.java
index 785894d81..7126f1181 100644
--- a/core/src/main/java/com/taobao/arthas/core/command/monitor200/WatchCommand.java
+++ b/core/src/main/java/com/taobao/arthas/core/command/monitor200/WatchCommand.java
@@ -42,7 +42,7 @@ public class WatchCommand extends EnhancerCommand {
private Integer sizeLimit = 10 * 1024 * 1024;
private boolean isRegEx = false;
private int numberOfLimit = 100;
-
+
@Argument(index = 0, argName = "class-pattern")
@Description("The full qualified class name you want to watch")
public void setClassPattern(String classPattern) {
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/command/CommandProcess.java b/core/src/main/java/com/taobao/arthas/core/shell/command/CommandProcess.java
index b3a12dbef..0c2694ff8 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/command/CommandProcess.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/command/CommandProcess.java
@@ -123,10 +123,9 @@ public interface CommandProcess extends Tty {
/**
* Register listener
*
- * @param lock the lock for enhance class
* @param listener
*/
- void register(int lock, AdviceListener listener, ClassFileTransformer transformer);
+ void register(AdviceListener listener, ClassFileTransformer transformer);
/**
* Unregister listener
diff --git a/core/src/main/java/com/taobao/arthas/core/shell/system/impl/ProcessImpl.java b/core/src/main/java/com/taobao/arthas/core/shell/system/impl/ProcessImpl.java
index b28b7875a..b09711172 100644
--- a/core/src/main/java/com/taobao/arthas/core/shell/system/impl/ProcessImpl.java
+++ b/core/src/main/java/com/taobao/arthas/core/shell/system/impl/ProcessImpl.java
@@ -384,9 +384,8 @@ public class ProcessImpl implements Process {
private final List args2;
private final Tty tty;
private final CommandLine commandLine;
- private int enhanceLock = -1;
private AtomicInteger times = new AtomicInteger();
- private AdviceListener suspendedListener = null;
+ private AdviceListener listener = null;
private ClassFileTransformer transformer;
public CommandProcessImpl(Process process, List args2, Tty tty, CommandLine commandLine) {
@@ -528,13 +527,15 @@ public class ProcessImpl implements Process {
}
@Override
- public void register(int enhanceLock, AdviceListener listener, ClassFileTransformer transformer) {
- this.enhanceLock = enhanceLock;
-
+ public void register(AdviceListener listener, ClassFileTransformer transformer) {
if (listener instanceof ProcessAware) {
- ((ProcessAware) listener).setProcess(this.process);
+ ProcessAware processAware = (ProcessAware) listener;
+ // listener 有可能是其它 command 创建的
+ if(processAware.getProcess() == null) {
+ processAware.setProcess(this.process);
+ }
}
- AdviceWeaver.reg(enhanceLock, listener);
+ AdviceWeaver.reg(listener);
this.transformer = transformer;
}
@@ -545,22 +546,29 @@ public class ProcessImpl implements Process {
ArthasBootstrap.getInstance().getTransformerManager().removeTransformer(transformer);
}
- AdviceWeaver.unReg(enhanceLock);
+ if (listener instanceof ProcessAware) {
+ // listener有可能其它 command 创建的,所以不能unRge
+ if (this.process.equals(((ProcessAware) listener).getProcess())) {
+ AdviceWeaver.unReg(listener);
+ }
+ } else {
+ AdviceWeaver.unReg(listener);
+ }
}
@Override
public void resume() {
- if (this.enhanceLock >= 0 && suspendedListener != null) {
- AdviceWeaver.resume(enhanceLock, suspendedListener);
- suspendedListener = null;
- }
+// if (suspendedListener != null) {
+// AdviceWeaver.resume(suspendedListener);
+// suspendedListener = null;
+// }
}
@Override
public void suspend() {
- if (this.enhanceLock >= 0) {
- suspendedListener = AdviceWeaver.suspend(enhanceLock);
- }
+// if (this.enhanceLock >= 0) {
+// suspendedListener = AdviceWeaver.suspend(enhanceLock);
+// }
}
@Override
diff --git a/core/src/main/java/com/taobao/arthas/core/util/affect/EnhancerAffect.java b/core/src/main/java/com/taobao/arthas/core/util/affect/EnhancerAffect.java
index a1bfb9e36..4189e708e 100644
--- a/core/src/main/java/com/taobao/arthas/core/util/affect/EnhancerAffect.java
+++ b/core/src/main/java/com/taobao/arthas/core/util/affect/EnhancerAffect.java
@@ -22,6 +22,7 @@ public final class EnhancerAffect extends Affect {
private final AtomicInteger cCnt = new AtomicInteger();
private final AtomicInteger mCnt = new AtomicInteger();
private ClassFileTransformer transformer;
+ private long listenerId;
/**
* dumpClass的文件存放集合
*/
@@ -92,6 +93,14 @@ public final class EnhancerAffect extends Affect {
this.transformer = transformer;
}
+ public long getListenerId() {
+ return listenerId;
+ }
+
+ public void setListenerId(long listenerId) {
+ this.listenerId = listenerId;
+ }
+
@Override
public String toString() {
final StringBuilder infoSB = new StringBuilder();
@@ -108,10 +117,11 @@ public final class EnhancerAffect extends Affect {
infoSB.append("[Affect method: ").append(method).append("]\n");
}
}
- infoSB.append(format("Affect(class count:%d , method count:%d) cost in %s ms.",
+ infoSB.append(format("Affect(class count: %d , method count: %d) cost in %s ms, listenerId: %d",
cCnt(),
mCnt(),
- cost()));
+ cost(),
+ listenerId));
return infoSB.toString();
}