diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java index d5474e234ce2..1d5c3b82d8d0 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java @@ -203,7 +203,10 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb public void paused(@NotNull SuspendContext suspendContext) { boolean isSuspendAll = suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_ALL; if (isSuspendAll && DebuggerUtils.isNewThreadSuspendStateTracking()) { + mergeSuspendThreadContextToSuspendAllContext(); resumeThreadsUnderEvaluationAndExplicitlyResumedAfterPause((SuspendContextImpl)suspendContext); + // It deletes suspend-thread stepping in another thread and suspend-all breakpoint is reached + getRequestsManager().deleteAllStepRequests(); } myThreadBlockedMonitor.stopWatching(!isSuspendAll ? suspendContext.getThread() : null); @@ -1203,6 +1206,21 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb myWaitFor.waitFor(timeout); } + private void mergeSuspendThreadContextToSuspendAllContext() { + boolean wasResumedSuspendThreadPausedContexts = false; + for (SuspendContextImpl anotherPausedContext : getSuspendManager().getPausedContexts()) { + if (anotherPausedContext.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD) { + getSuspendManager().resume(anotherPausedContext); + wasResumedSuspendThreadPausedContexts = true; + } + } + if (wasResumedSuspendThreadPausedContexts) { + XDebuggerManagerImpl.getNotificationGroup() + .createNotification(JavaDebuggerBundle.message("message.switched.to.suspend.all.context"), MessageType.WARNING) + .notify(getProject()); + } + //mySteppingProgressTracker.cancelAllSteppings(); + } private void resumeThreadsUnderEvaluationAndExplicitlyResumedAfterPause(@NotNull SuspendContextImpl suspendAllContext) { for (SuspendContextImpl suspendContext : mySuspendManager.getEventContexts()) { diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/SteppingProgressTracker.kt b/java/debugger/impl/src/com/intellij/debugger/engine/SteppingProgressTracker.kt index de5930c9224f..4da4e9ed5eb1 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/SteppingProgressTracker.kt +++ b/java/debugger/impl/src/com/intellij/debugger/engine/SteppingProgressTracker.kt @@ -25,7 +25,9 @@ internal class SteppingProgressTracker(private val debuggerProcessImpl: DebugPro /** returns true iff the [suspendContext] is the end of ongoing stepping */ fun onPaused(suspendContext: SuspendContext): Boolean { val thread = suspendContext.thread - val completedSteps = trackedStepping.filter { it.threadFilter(thread, suspendContext as SuspendContextImpl) } + val completedSteps = if (suspendContext.suspendPolicy == EventRequest.SUSPEND_ALL) trackedStepping + else trackedStepping.filter { it.threadFilter(thread, suspendContext as SuspendContextImpl) } + for ((stepCompetedStatus, _) in completedSteps) { stepCompetedStatus.complete(Unit) } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java index 692afbdba467..b9d81348763c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java @@ -26,6 +26,7 @@ import com.sun.jdi.event.ClassPrepareEvent; import com.sun.jdi.event.EventSet; import com.sun.jdi.request.*; import one.util.streamex.StreamEx; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -482,4 +483,14 @@ public class RequestManagerImpl extends DebugProcessAdapterImpl implements Reque } return false; } + + @ApiStatus.Internal + public void deleteAllStepRequests() { + List stepRequestors = + ContainerUtil.filter(myRequestorToBelongedRequests.keySet(), request -> request instanceof StepRequestor); + + for (Requestor request : stepRequestors) { + deleteRequest(request); + } + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java index bb25a1da8548..cb969ee86aae 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java @@ -706,7 +706,7 @@ public final class DebuggerSession implements AbstractDebuggerSession { } final ThreadReferenceProxyImpl newThread = suspendContext.getEventThread(); - if (newThread == null || suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_ALL || !myDebugProcess.isSteppingInProgress()) { + if (newThread == null || !myDebugProcess.isSteppingInProgress()) { if (suspendContext.threadFilterWasPassed) { return true; } diff --git a/java/debugger/openapi/resources/messages/JavaDebuggerBundle.properties b/java/debugger/openapi/resources/messages/JavaDebuggerBundle.properties index ccc322b6faed..1896f9cb3df8 100644 --- a/java/debugger/openapi/resources/messages/JavaDebuggerBundle.properties +++ b/java/debugger/openapi/resources/messages/JavaDebuggerBundle.properties @@ -82,6 +82,7 @@ message.breakpoint.skipped.learn.more=Troubleshooting guide message.other.threads.reached.breakpoints={0,choice,1#Another thread also reached a breakpoint|2#{0} other threads also reached breakpoints} message.resumed.other.threads.while.stepping=Resumed all threads because the "#{0}" thread is not in the "RUNNING" state message.run.to.cursor.paused.in.another.thread=Suspended in another thread +message.switched.to.suspend.all.context=Context was switched to the suspend-all breakpoint error.invalid.argument={0,choice, 1#Invalid argument|2#Invalid arguments} error.vm.disconnected=VM disconnected. Target virtual machine closed connection error.unknown.host=Cannot connect to remote process. Host is unknown