Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,15 @@ public void setAsync(boolean async) {
this.async = async;
}

@Override
public void setSuspendPolicy(String policy) {
}

@Override
public String getSuspendPolicy() {
return DebugSettings.getCurrent().suspendAllThreads ? "SUSPEND_ALL" : "SUSPEND_EVENT_THREAD";
}

@Override
public CompletableFuture<IBreakpoint> install() {
// It's possible that different class loaders create new class with the same name.
Expand Down Expand Up @@ -412,7 +421,11 @@ private CompletableFuture<List<BreakpointRequest>> createBreakpointRequests(List

newLocations.forEach(location -> {
BreakpointRequest request = vm.eventRequestManager().createBreakpointRequest(location);
request.setSuspendPolicy(BreakpointRequest.SUSPEND_EVENT_THREAD);
if ("SUSPEND_ALL".equals(getSuspendPolicy())) {
request.setSuspendPolicy(BreakpointRequest.SUSPEND_ALL);
} else {
request.setSuspendPolicy(BreakpointRequest.SUSPEND_EVENT_THREAD);
}
if (hitCount > 0) {
request.addCountFilter(hitCount);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public final class DebugSettings {
public int jdwpRequestTimeout = 3000;
public AsyncMode asyncJDWP = AsyncMode.OFF;
public Switch debugSupportOnDecompiledSource = Switch.OFF;
public boolean suspendAllThreads = false;

public static DebugSettings getCurrent() {
return current;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,8 @@ private static StepRequest createStepRequest(ThreadReference thread, int stepSiz
request.addClassExclusionFilter(exclusionFilter);
}
}
request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
boolean suspendAll = DebugSettings.getCurrent().suspendAllThreads;
request.setSuspendPolicy(suspendAll ? EventRequest.SUSPEND_ALL : EventRequest.SUSPEND_EVENT_THREAD);
request.addCountFilter(1);

return request;
Expand All @@ -415,7 +416,8 @@ public static CompletableFuture<Long> stopOnEntry(IDebugSession debugSession, St
EventRequestManager manager = debugSession.getVM().eventRequestManager();
MethodEntryRequest request = manager.createMethodEntryRequest();
request.addClassFilter(mainClass);
request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
boolean suspendAll = DebugSettings.getCurrent().suspendAllThreads;
request.setSuspendPolicy(suspendAll ? EventRequest.SUSPEND_ALL : EventRequest.SUSPEND_EVENT_THREAD);

debugSession.getEventHub().events().filter(debugEvent -> {
return debugEvent.event instanceof MethodEntryEvent && request.equals(debugEvent.event.request());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,11 @@ default void setAsync(boolean async) {
default boolean async() {
return false;
}

default void setSuspendPolicy(String policy) {
}

default String getSuspendPolicy() {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.event.ClassPrepareEvent;
import com.sun.jdi.event.ThreadDeathEvent;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.ClassPrepareRequest;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.MethodEntryRequest;
Expand Down Expand Up @@ -262,7 +263,8 @@ private Optional<MethodEntryRequest> createMethodEntryRequest0(ReferenceType typ
MethodEntryRequest request = vm.eventRequestManager().createMethodEntryRequest();

request.addClassFilter(type);
request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
boolean suspendAll = DebugSettings.getCurrent().suspendAllThreads;
request.setSuspendPolicy(suspendAll ? EventRequest.SUSPEND_ALL : EventRequest.SUSPEND_EVENT_THREAD);
if (hitCount > 0) {
request.addCountFilter(hitCount);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.event.ClassPrepareEvent;
import com.sun.jdi.event.ThreadDeathEvent;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.ClassPrepareRequest;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.WatchpointRequest;
Expand Down Expand Up @@ -212,7 +213,8 @@ private List<WatchpointRequest> createWatchpointRequests(ReferenceType type) {
}

watchpointRequests.forEach(request -> {
request.setSuspendPolicy(WatchpointRequest.SUSPEND_EVENT_THREAD);
boolean suspendAll = DebugSettings.getCurrent().suspendAllThreads;
request.setSuspendPolicy(suspendAll ? EventRequest.SUSPEND_ALL : EventRequest.SUSPEND_EVENT_THREAD);
if (hitCount > 0) {
request.addCountFilter(hitCount);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,15 @@
import java.util.logging.Logger;

import com.microsoft.java.debug.core.Configuration;
import com.microsoft.java.debug.core.DebugSettings;
import com.microsoft.java.debug.core.DebugSettings.IDebugSettingChangeListener;
import com.microsoft.java.debug.core.IBreakpoint;
import com.microsoft.java.debug.core.IDebugResource;
import com.microsoft.java.debug.core.IMethodBreakpoint;
import com.microsoft.java.debug.core.IWatchpoint;
import com.sun.jdi.VMDisconnectedException;

public class BreakpointManager implements IBreakpointManager {
public class BreakpointManager implements IBreakpointManager, IDebugSettingChangeListener {
private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME);
/**
* A collection of breakpoints registered with this manager.
Expand All @@ -47,6 +51,7 @@ public BreakpointManager() {
this.sourceToBreakpoints = new HashMap<>();
this.watchpoints = new HashMap<>();
this.methodBreakpoints = new HashMap<>();
DebugSettings.addDebugSettingChangeListener(this);
}

@Override
Expand Down Expand Up @@ -268,4 +273,50 @@ public IMethodBreakpoint[] setMethodBreakpoints(IMethodBreakpoint[] breakpoints)
private String getMethodBreakpointKey(IMethodBreakpoint breakpoint) {
return breakpoint.className() + "#" + breakpoint.methodName();
}

@Override
public void update(DebugSettings oldSettings, DebugSettings newSettings) {
// If suspend policy changed, recreate all breakpoints with new policy
if (oldSettings.suspendAllThreads != newSettings.suspendAllThreads) {
// Recreate all line breakpoints
synchronized (breakpoints) {
for (IBreakpoint bp : breakpoints) {
reinstallBreakpoint(bp);
}
}

// Recreate all watchpoints
for (IWatchpoint wp : watchpoints.values()) {
if (wp != null) {
reinstallBreakpoint(wp);
}
}

// Recreate all method breakpoints
for (IMethodBreakpoint mbp : methodBreakpoints.values()) {
if (mbp != null) {
reinstallBreakpoint(mbp);
}
}
}
}

private void reinstallBreakpoint(IDebugResource resource) {
try {
// Close (delete) existing event requests
resource.close();
// Reinstall with new suspend policy (which will be read from DebugSettings)
if (resource instanceof IBreakpoint) {
((IBreakpoint) resource).install();
} else if (resource instanceof IWatchpoint) {
((IWatchpoint) resource).install();
} else if (resource instanceof IMethodBreakpoint) {
((IMethodBreakpoint) resource).install();
}
} catch (VMDisconnectedException ex) {
// Ignore since reinstalling breakpoints is meaningless when JVM is disconnected.
} catch (Exception e) {
logger.log(Level.WARNING, String.format("Failed to reinstall breakpoint: %s", e.toString()), e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.sun.jdi.event.ThreadStartEvent;
import com.sun.jdi.event.VMDeathEvent;
import com.sun.jdi.event.VMDisconnectEvent;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.event.VMStartEvent;

public class ConfigurationDoneRequestHandler implements IDebugRequestHandler {
Expand Down Expand Up @@ -119,7 +120,9 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession,
((ExceptionEvent) event).catchLocation() == null);
context.getExceptionManager().setException(thread.uniqueID(), jdiException);
context.getThreadCache().addEventThread(thread, "exception");
context.getProtocolServer().sendEvent(new Events.StoppedEvent("exception", thread.uniqueID()));
boolean allThreadsStopped = event.request() != null
&& event.request().suspendPolicy() == EventRequest.SUSPEND_ALL;
context.getProtocolServer().sendEvent(new Events.StoppedEvent("exception", thread.uniqueID(), allThreadsStopped));
debugEvent.shouldResume = false;
} else {
isImportantEvent = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.sun.jdi.IncompatibleThreadStateException;
import com.sun.jdi.StackFrame;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.StepRequest;

/**
Expand Down Expand Up @@ -121,7 +122,8 @@ private void stepInto(IDebugAdapterContext context, ThreadReference thread) {
debugEvent.shouldResume = false;
// Have to send two events to keep the UI sync with the step in operations:
context.getProtocolServer().sendEvent(new Events.ContinuedEvent(thread.uniqueID()));
context.getProtocolServer().sendEvent(new Events.StoppedEvent("restartframe", thread.uniqueID()));
boolean allThreadsStopped = request.suspendPolicy() == EventRequest.SUSPEND_ALL;
context.getProtocolServer().sendEvent(new Events.StoppedEvent("restartframe", thread.uniqueID(), allThreadsStopped));
context.getThreadCache().setThreadStoppedReason(thread.uniqueID(), "restartframe");
});
request.enable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,15 +212,19 @@ private void registerBreakpointHandler(IDebugAdapterContext context) {
debugEvent.eventSet.resume();
} else {
context.getThreadCache().addEventThread(bpThread, breakpointName);
boolean allThreadsStopped = event.request() != null
&& event.request().suspendPolicy() == EventRequest.SUSPEND_ALL;
context.getProtocolServer().sendEvent(new Events.StoppedEvent(
breakpointName, bpThread.uniqueID()));
breakpointName, bpThread.uniqueID(), allThreadsStopped));
}
});
});
} else {
context.getThreadCache().addEventThread(bpThread, breakpointName);
boolean allThreadsStopped = event.request() != null
&& event.request().suspendPolicy() == EventRequest.SUSPEND_ALL;
context.getProtocolServer().sendEvent(new Events.StoppedEvent(
breakpointName, bpThread.uniqueID()));
breakpointName, bpThread.uniqueID(), allThreadsStopped));
}
debugEvent.shouldResume = false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import com.sun.jdi.ThreadReference;
import com.sun.jdi.event.Event;
import com.sun.jdi.event.WatchpointEvent;
import com.sun.jdi.request.EventRequest;

public class SetDataBreakpointsRequestHandler implements IDebugRequestHandler {
private boolean registered = false;
Expand Down Expand Up @@ -152,13 +153,17 @@ private void registerWatchpointHandler(IDebugAdapterContext context) {
debugEvent.eventSet.resume();
} else {
context.getThreadCache().addEventThread(bpThread, "data breakpoint");
context.getProtocolServer().sendEvent(new Events.StoppedEvent("data breakpoint", bpThread.uniqueID()));
boolean allThreadsStopped = event.request() != null
&& event.request().suspendPolicy() == EventRequest.SUSPEND_ALL;
context.getProtocolServer().sendEvent(new Events.StoppedEvent("data breakpoint", bpThread.uniqueID(), allThreadsStopped));
}
});
});
} else {
context.getThreadCache().addEventThread(bpThread, "data breakpoint");
context.getProtocolServer().sendEvent(new Events.StoppedEvent("data breakpoint", bpThread.uniqueID()));
boolean allThreadsStopped = event.request() != null
&& event.request().suspendPolicy() == EventRequest.SUSPEND_ALL;
context.getProtocolServer().sendEvent(new Events.StoppedEvent("data breakpoint", bpThread.uniqueID(), allThreadsStopped));
}
debugEvent.shouldResume = false;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.microsoft.java.debug.core.protocol.Types.FunctionBreakpoint;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.event.MethodEntryEvent;
import com.sun.jdi.request.EventRequest;

public class SetFunctionBreakpointsRequestHandler implements IDebugRequestHandler {
private boolean registered = false;
Expand Down Expand Up @@ -166,16 +167,20 @@ private void registerMethodBreakpointHandler(IDebugAdapterContext context) {
debugEvent.eventSet.resume();
} else {
context.getThreadCache().addEventThread(bpThread, "function breakpoint");
boolean allThreadsStopped = methodEntryEvent.request() != null
&& methodEntryEvent.request().suspendPolicy() == EventRequest.SUSPEND_ALL;
context.getProtocolServer().sendEvent(new Events.StoppedEvent(
"function breakpoint", bpThread.uniqueID()));
"function breakpoint", bpThread.uniqueID(), allThreadsStopped));
}
});
});

} else {
context.getThreadCache().addEventThread(bpThread, "function breakpoint");
boolean allThreadsStopped = methodEntryEvent.request() != null
&& methodEntryEvent.request().suspendPolicy() == EventRequest.SUSPEND_ALL;
context.getProtocolServer()
.sendEvent(new Events.StoppedEvent("function breakpoint", bpThread.uniqueID()));
.sendEvent(new Events.StoppedEvent("function breakpoint", bpThread.uniqueID(), allThreadsStopped));
}

debugEvent.shouldResume = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import com.microsoft.java.debug.core.AsyncJdwpUtils;
import com.microsoft.java.debug.core.DebugEvent;
import com.microsoft.java.debug.core.DebugSettings;
import com.microsoft.java.debug.core.DebugUtility;
import com.microsoft.java.debug.core.IDebugSession;
import com.microsoft.java.debug.core.JdiExceptionReference;
Expand All @@ -48,6 +49,7 @@
import com.sun.jdi.StackFrame;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.Value;
import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.VoidValue;
import com.sun.jdi.event.BreakpointEvent;
import com.sun.jdi.event.Event;
Expand Down Expand Up @@ -112,8 +114,16 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
threadState.pendingStepRequest = DebugUtility.createStepOverRequest(thread, null);
}

if (DebugSettings.getCurrent().suspendAllThreads) {
threadState.pendingStepRequest.setSuspendPolicy(EventRequest.SUSPEND_ALL);
}

threadState.pendingMethodExitRequest = thread.virtualMachine().eventRequestManager().createMethodExitRequest();
threadState.pendingMethodExitRequest.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
if (DebugSettings.getCurrent().suspendAllThreads) {
threadState.pendingMethodExitRequest.setSuspendPolicy(EventRequest.SUSPEND_ALL);
} else {
threadState.pendingMethodExitRequest.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
}

threadState.targetStepIn = targetId > 0
? (MethodInvocation) context.getRecyclableIdPool().getObjectById(targetId) : null;
Expand Down Expand Up @@ -189,7 +199,15 @@ public CompletableFuture<Response> handle(Command command, Arguments arguments,
}

context.getThreadCache().removeEventThread(thread.uniqueID());
DebugUtility.resumeThread(thread);
if (DebugSettings.getCurrent().suspendAllThreads) {
try {
context.getDebugSession().resume();
} catch (VMDisconnectedException e) {
// ignore
}
} else {
DebugUtility.resumeThread(thread);
}
ThreadsRequestHandler.checkThreadRunningAndRecycleIds(thread, context);
} catch (IncompatibleThreadStateException ex) {
// Roll back the Exception info if stepping fails.
Expand Down Expand Up @@ -310,7 +328,9 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession,
threadState.eventSubscription.dispose();
}
context.getThreadCache().addEventThread(thread, "step");
context.getProtocolServer().sendEvent(new Events.StoppedEvent("step", thread.uniqueID()));
boolean allThreadsStopped = event.request() != null
&& event.request().suspendPolicy() == EventRequest.SUSPEND_ALL;
context.getProtocolServer().sendEvent(new Events.StoppedEvent("step", thread.uniqueID(), allThreadsStopped));
debugEvent.shouldResume = false;
} else if (event instanceof MethodExitEvent) {
MethodExitEvent methodExitEvent = (MethodExitEvent) event;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.commons.lang3.StringUtils;

import com.microsoft.java.debug.core.AsyncJdwpUtils;
import com.microsoft.java.debug.core.DebugSettings;
import com.microsoft.java.debug.core.DebugUtility;
import com.microsoft.java.debug.core.adapter.AdapterUtils;
import com.microsoft.java.debug.core.adapter.ErrorCode;
Expand Down Expand Up @@ -149,6 +150,11 @@ private CompletableFuture<Response> resume(Requests.ContinueArguments arguments,
if (thread == null) {
thread = DebugUtility.getThread(context.getDebugSession(), arguments.threadId);
}

if (DebugSettings.getCurrent().suspendAllThreads) {
thread = null;
}

/**
* See the jdi doc https://docs.oracle.com/javase/7/docs/jdk/api/jpda/jdi/com/sun/jdi/ThreadReference.html#resume(),
* suspends of both the virtual machine and individual threads are counted. Before a thread will run again, it must
Expand Down
Loading
Loading