use thread filter when watching method return values

This commit is contained in:
Eugene Zhuravlev
2010-08-27 16:05:33 +04:00
parent 0fadf89437
commit cc5a173fbc
3 changed files with 47 additions and 32 deletions
@@ -44,7 +44,6 @@ import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.event.*;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.MethodExitRequest;
/**
* @author lex
@@ -133,7 +132,7 @@ public class DebugProcessEvents extends DebugProcessImpl {
while (!isStopped()) {
try {
final EventSet eventSet = eventQueue.remove();
if (myReturnValueWatcher != null && myReturnValueWatcher.isTrackingEnabled()) {
if (myReturnValueWatcher != null && myReturnValueWatcher.isEnabled()) {
int processed = 0;
for (EventIterator eventIterator = eventSet.eventIterator(); eventIterator.hasNext();) {
final Event event = eventIterator.nextEvent();
@@ -264,9 +263,7 @@ public class DebugProcessEvents extends DebugProcessImpl {
if(myState.compareAndSet(STATE_INITIAL, STATE_ATTACHED)) {
final VirtualMachineProxyImpl machineProxy = getVirtualMachineProxy();
if (machineProxy.canGetMethodReturnValues()) {
MethodExitRequest request = machineProxy.eventRequestManager().createMethodExitRequest();
request.setSuspendPolicy(EventRequest.SUSPEND_NONE);
myReturnValueWatcher = new MethodReturnValueWatcher(request);
myReturnValueWatcher = new MethodReturnValueWatcher(machineProxy.eventRequestManager());
}
DebuggerManagerEx.getInstanceEx(getProject()).getBreakpointManager().setInitialBreakpointsState();
@@ -310,7 +307,7 @@ public class DebugProcessEvents extends DebugProcessImpl {
}
private void processStepEvent(SuspendContextImpl suspendContext, StepEvent event) {
ThreadReference thread = event.thread();
final ThreadReference thread = event.thread();
//LOG.assertTrue(thread.isSuspended());
preprocessEvent(suspendContext, thread);
@@ -340,7 +337,7 @@ public class DebugProcessEvents extends DebugProcessImpl {
else {
showStatusText("");
if (myReturnValueWatcher != null) {
myReturnValueWatcher.setTrackingEnabled(false);
myReturnValueWatcher.disable();
}
getSuspendManager().voteSuspend(suspendContext);
}
@@ -404,7 +401,7 @@ public class DebugProcessEvents extends DebugProcessImpl {
}
else {
if (myReturnValueWatcher != null) {
myReturnValueWatcher.setTrackingEnabled(false);
myReturnValueWatcher.disable();
}
if (suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_ALL) {
// there could be explicit resume as a result of call to voteSuspend()
@@ -1383,7 +1383,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
RequestHint hint = new RequestHint(thread, suspendContext, StepRequest.STEP_OUT);
hint.setIgnoreFilters(mySession.shouldIgnoreSteppingFilters());
if (myReturnValueWatcher != null) {
myReturnValueWatcher.setTrackingEnabled(true);
myReturnValueWatcher.enable(thread.getThreadReference());
}
doStep(suspendContext, thread, StepRequest.STEP_OUT, hint);
super.contextAction();
@@ -1441,7 +1441,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
hint.setIgnoreFilters(myIsIgnoreBreakpoints || mySession.shouldIgnoreSteppingFilters());
if (myReturnValueWatcher != null) {
myReturnValueWatcher.setTrackingEnabled(true);
myReturnValueWatcher.enable(steppingThread.getThreadReference());
}
doStep(suspendContext, steppingThread, StepRequest.STEP_OVER, hint);
@@ -20,10 +20,12 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.ArrayUtil;
import com.sun.jdi.Method;
import com.sun.jdi.ObjectCollectedException;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.Value;
import com.sun.jdi.event.MethodExitEvent;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.EventRequestManager;
import com.sun.jdi.request.MethodExitRequest;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.InvocationTargetException;
@@ -36,19 +38,19 @@ public class MethodReturnValueWatcher {
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.requests.MethodReturnValueWatcher");
private @Nullable Method myLastExecutedMethod;
private @Nullable Value myLastMethodReturnValue;
private @NotNull final MethodExitRequest myWatchMethodReturnValueRequest;
private @Nullable MethodExitRequest myRequest;
private java.lang.reflect.Method myReturnValueMethod;
private volatile boolean myIsTrackingEnabled;
private volatile boolean myEnabled;
private boolean myFeatureEnabled;
private final EventRequestManager myRequestManager;
public MethodReturnValueWatcher(final MethodExitRequest request) {
myWatchMethodReturnValueRequest = request;
myIsTrackingEnabled = request.isEnabled();
public MethodReturnValueWatcher(EventRequestManager requestManager) {
myRequestManager = requestManager;
myFeatureEnabled = DebuggerSettings.getInstance().WATCH_RETURN_VALUES;
}
public boolean processMethodExitEvent(MethodExitEvent event) {
if (event.request() != myWatchMethodReturnValueRequest) {
if (event.request() != myRequest) {
return false;
}
try {
@@ -95,38 +97,54 @@ public class MethodReturnValueWatcher {
return myFeatureEnabled;
}
public boolean isTrackingEnabled() {
return myIsTrackingEnabled;
public boolean isEnabled() {
return myEnabled;
}
public void setFeatureEnabled(final boolean featureEnabled) {
myFeatureEnabled = featureEnabled;
updateRequestState(featureEnabled && myIsTrackingEnabled);
myLastExecutedMethod = null;
myLastMethodReturnValue = null;
}
public void setTrackingEnabled(boolean trackingEnabled) {
myIsTrackingEnabled = trackingEnabled;
updateRequestState(trackingEnabled && myFeatureEnabled);
public void enable(ThreadReference thread) {
setTrackingEnabled(true, thread);
}
public void disable() {
setTrackingEnabled(false, null);
}
private void setTrackingEnabled(boolean trackingEnabled, final ThreadReference thread) {
myEnabled = trackingEnabled;
updateRequestState(trackingEnabled && myFeatureEnabled, thread);
}
private void updateRequestState(final boolean enabled) {
private void updateRequestState(final boolean enabled, @Nullable final ThreadReference thread) {
try {
final MethodExitRequest request = myRequest;
if (request != null) {
myRequest = null;
myRequestManager.deleteEventRequest(request);
}
if (enabled) {
myLastExecutedMethod = null;
myLastMethodReturnValue = null;
if (!myWatchMethodReturnValueRequest.isEnabled()) {
myWatchMethodReturnValueRequest.enable();
}
}
else {
if (myWatchMethodReturnValueRequest.isEnabled()) {
myWatchMethodReturnValueRequest.disable();
}
myRequest = createRequest(thread);
myRequest.enable();
}
}
catch (ObjectCollectedException ignored) {
}
}
private MethodExitRequest createRequest(@Nullable final ThreadReference thread) {
final MethodExitRequest request = myRequestManager.createMethodExitRequest();
request.setSuspendPolicy(EventRequest.SUSPEND_NONE);
if (thread != null) {
request.addThreadFilter(thread);
}
return request;
}
}