Skip to content

Commit

Permalink
threadlocal leak
Browse files Browse the repository at this point in the history
Signed-off-by: binbin <[email protected]>
  • Loading branch information
binbin committed Jun 20, 2022
1 parent 639aae9 commit 8c362ac
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -42,6 +43,9 @@ public class EventListenerHandler implements SpyHandler {
private final Map<Integer/*LISTENER_ID*/, EventProcessor> mappingOfEventProcessor
= new ConcurrentHashMap<Integer, EventProcessor>();

// 冻结标识
private AtomicBoolean frozen = new AtomicBoolean(false);

/**
* 注册事件处理器
*
Expand All @@ -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;
Expand Down Expand Up @@ -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={};",
Expand Down Expand Up @@ -229,6 +237,10 @@ private Spy.Ret handleEvent(final int listenerId,
throwable
);
}
} finally {
if (frozen.get()) {
mappingOfEventProcessor.remove(listenerId);
}
}

// 默认返回不进行任何流程变更
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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();
}
}
Expand All @@ -385,6 +402,12 @@ private Spy.Ret handleOnEnd(final int listenerId,
return newInstanceForNone();
}

// 如果已经冻结则不需要响应
if (frozen.get()) {
return newInstanceForNone();
}


final EventProcessor wrap = mappingOfEventProcessor.get(listenerId);

// 如果尚未注册,则直接返回,不做任何处理
Expand All @@ -400,6 +423,7 @@ private Spy.Ret handleOnEnd(final int listenerId,
// 2. super.<init>
// 处理方式是直接返回,不做任何事件的处理和代码流程的改变,放弃对super.<init>的观察,可惜了
if (process.isEmptyStack()) {
wrap.processRef.remove();
return newInstanceForNone();
}

Expand Down Expand Up @@ -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);
Expand All @@ -465,6 +494,7 @@ public void handleOnCallBefore(int listenerId, int lineNumber, String owner, Str
// super.<init>会导致CALL_BEFORE事件优先于BEFORE事件
// 但如果按照现在的架构要兼容这种情况,比较麻烦,所以暂时先放弃了这部分的消息,可惜可惜
if (process.isEmptyStack()) {
wrap.processRef.remove();
return;
}

Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down Expand Up @@ -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) {
Expand All @@ -582,6 +628,7 @@ public void handleOnLine(int listenerId, int lineNumber) throws Throwable {
// 如果当前调用过程信息堆栈是空的,说明BEFORE/LINE错位
// 处理方式是直接返回,不做任何事件的处理和代码流程的改变
if (process.isEmptyStack()) {
wrap.processRef.remove();
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/**
Expand Down

0 comments on commit 8c362ac

Please sign in to comment.