diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandler.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandler.java index 64036987..53b0b27f 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandler.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandler.java @@ -15,6 +15,7 @@ import java.com.alibaba.jvm.sandbox.spy.SpyHandler; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import static com.alibaba.jvm.sandbox.api.event.Event.Type.IMMEDIATELY_RETURN; @@ -42,6 +43,9 @@ public class EventListenerHandler implements SpyHandler { private final Map mappingOfEventProcessor = new ConcurrentHashMap(); + // 冻结标识 + private AtomicBoolean frozen = new AtomicBoolean(false); + /** * 注册事件处理器 * @@ -66,7 +70,8 @@ public void active(final int listenerId, * @param listenerId 事件处理器ID */ public void frozen(int listenerId) { - final EventProcessor processor = mappingOfEventProcessor.remove(listenerId); + frozen.set(true); + final EventProcessor processor = mappingOfEventProcessor.get(listenerId); if (null == processor) { logger.debug("ignore frozen listener={}, because not found.", listenerId); return; @@ -121,6 +126,9 @@ private Spy.Ret handleEvent(final int listenerId, catch (ProcessControlException pce) { final EventProcessor.Process process = processor.processRef.get(); + if (process.isEmptyStack()) { + processor.processRef.remove(); + } final ProcessControlException.State state = pce.getState(); logger.debug("on-event: event|{}|{}|{}|{}, process-changed: {}. isIgnoreProcessEvent={};", @@ -229,6 +237,10 @@ private Spy.Ret handleEvent(final int listenerId, throwable ); } + } finally { + if (frozen.get()) { + mappingOfEventProcessor.remove(listenerId); + } } // 默认返回不进行任何流程变更 @@ -311,6 +323,11 @@ public Spy.Ret handleOnBefore(int listenerId, int targetClassLoaderObjectID, Obj return newInstanceForNone(); } + // 如果已经冻结则不需要响应 + if (frozen.get()) { + return newInstanceForNone(); + } + // 获取事件处理器 final EventProcessor processor = mappingOfEventProcessor.get(listenerId); @@ -358,18 +375,18 @@ public Spy.Ret handleOnBefore(int listenerId, int targetClassLoaderObjectID, Obj @Override public Spy.Ret handleOnThrows(int listenerId, Throwable throwable) throws Throwable { - try{ + try { return handleOnEnd(listenerId, throwable, false); - }finally { + } finally { BusinessClassLoaderHolder.removeBussinessClassLoader(); } } @Override public Spy.Ret handleOnReturn(int listenerId, Object object) throws Throwable { - try{ + try { return handleOnEnd(listenerId, object, true); - }finally { + } finally { BusinessClassLoaderHolder.removeBussinessClassLoader(); } } @@ -385,6 +402,12 @@ private Spy.Ret handleOnEnd(final int listenerId, return newInstanceForNone(); } + // 如果已经冻结则不需要响应 + if (frozen.get()) { + return newInstanceForNone(); + } + + final EventProcessor wrap = mappingOfEventProcessor.get(listenerId); // 如果尚未注册,则直接返回,不做任何处理 @@ -400,6 +423,7 @@ private Spy.Ret handleOnEnd(final int listenerId, // 2. super. // 处理方式是直接返回,不做任何事件的处理和代码流程的改变,放弃对super.的观察,可惜了 if (process.isEmptyStack()) { + wrap.processRef.remove(); return newInstanceForNone(); } @@ -451,6 +475,11 @@ public void handleOnCallBefore(int listenerId, int lineNumber, String owner, Str return; } + // 如果已经冻结则不需要响应 + if (frozen.get()) { + return; + } + final EventProcessor wrap = mappingOfEventProcessor.get(listenerId); if (null == wrap) { logger.debug("listener={} is not activated, ignore processing call-before-event.", listenerId); @@ -465,6 +494,7 @@ public void handleOnCallBefore(int listenerId, int lineNumber, String owner, Str // super.会导致CALL_BEFORE事件优先于BEFORE事件 // 但如果按照现在的架构要兼容这种情况,比较麻烦,所以暂时先放弃了这部分的消息,可惜可惜 if (process.isEmptyStack()) { + wrap.processRef.remove(); return; } @@ -495,6 +525,11 @@ public void handleOnCallReturn(int listenerId) throws Throwable { return; } + // 如果已经冻结则不需要响应 + if (frozen.get()) { + return; + } + final EventProcessor wrap = mappingOfEventProcessor.get(listenerId); if (null == wrap) { logger.debug("listener={} is not activated, ignore processing call-return-event.", listenerId); @@ -503,6 +538,7 @@ public void handleOnCallReturn(int listenerId) throws Throwable { final EventProcessor.Process process = wrap.processRef.get(); if (process.isEmptyStack()) { + wrap.processRef.remove(); return; } @@ -533,6 +569,11 @@ public void handleOnCallThrows(int listenerId, String throwException) throws Thr return; } + // 如果已经冻结则不需要响应 + if (frozen.get()) { + return; + } + final EventProcessor wrap = mappingOfEventProcessor.get(listenerId); if (null == wrap) { logger.debug("listener={} is not activated, ignore processing call-throws-event.", listenerId); @@ -541,6 +582,7 @@ public void handleOnCallThrows(int listenerId, String throwException) throws Thr final EventProcessor.Process process = wrap.processRef.get(); if (process.isEmptyStack()) { + wrap.processRef.remove(); return; } @@ -570,6 +612,10 @@ public void handleOnLine(int listenerId, int lineNumber) throws Throwable { logger.debug("listener={} is in protecting, ignore processing call-line-event", listenerId); return; } + // 如果已经冻结则不需要响应 + if (frozen.get()) { + return; + } final EventProcessor wrap = mappingOfEventProcessor.get(listenerId); if (null == wrap) { @@ -582,6 +628,7 @@ public void handleOnLine(int listenerId, int lineNumber) throws Throwable { // 如果当前调用过程信息堆栈是空的,说明BEFORE/LINE错位 // 处理方式是直接返回,不做任何事件的处理和代码流程的改变 if (process.isEmptyStack()) { + wrap.processRef.remove(); return; } diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/SandboxProtector.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/SandboxProtector.java index 77ff6674..898603d7 100644 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/SandboxProtector.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/SandboxProtector.java @@ -69,7 +69,12 @@ public int exitProtecting() { * @return TRUE:在守护区域中;FALSE:非守护区域中 */ public boolean isInProtecting() { - return isInProtectingThreadLocal.get().get() > 0; + AtomicInteger inProtect = isInProtectingThreadLocal.get(); + if (inProtect.get() <= 0) { + isInProtectingThreadLocal.remove(); + return false; + } + return true; } /**