IDEA-43728 Provide a way to step in a chosen thread while others remain suspended
authorEgor.Ushakov <egor.ushakov@jetbrains.com>
Mon, 6 Jul 2015 09:42:39 +0000 (12:42 +0300)
committerEgor.Ushakov <egor.ushakov@jetbrains.com>
Mon, 6 Jul 2015 09:43:58 +0000 (12:43 +0300)
java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java
java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerImpl.java
platform/util/resources/misc/registry.properties

index 4e23d5a93f97538ec796c1f92d6bf157e7dbf01a..03814017244b388c1019ad1475ccf80fd1ac1c60 100644 (file)
@@ -193,8 +193,14 @@ public class DebugProcessEvents extends DebugProcessImpl {
                   // check if there is already one request with policy SUSPEND_ALL
                   for (SuspendContextImpl context : getSuspendManager().getEventContexts()) {
                     if (context.getSuspendPolicy() == EventRequest.SUSPEND_ALL) {
-                      eventSet.resume();
-                      return;
+                      for (Event event : eventSet) {
+                        if (event instanceof LocatableEvent && SuspendManagerUtil.isEvaluating(getSuspendManager(),
+                                                          getVirtualMachineProxy().getThreadReferenceProxy(
+                                                            ((LocatableEvent)event).thread()))) {
+                          eventSet.resume();
+                          return;
+                        }
+                      }
                     }
                   }
                 }
index 9da93a15cda67d2952f90290aa95d679a7cf56bc..3215d726ad365edf5b36ceb7008b570501067d98 100644 (file)
@@ -56,6 +56,7 @@ import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.UserDataHolderBase;
+import com.intellij.openapi.util.registry.Registry;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.wm.ToolWindowId;
 import com.intellij.openapi.wm.impl.status.StatusBarUtil;
@@ -406,7 +407,8 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
       // suspend policy to match the suspend policy of the context:
       // if all threads were suspended, then during stepping all the threads must be suspended
       // if only event thread were suspended, then only this particular thread must be suspended during stepping
-      stepRequest.setSuspendPolicy(suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD? EventRequest.SUSPEND_EVENT_THREAD : EventRequest.SUSPEND_ALL);
+      stepRequest.setSuspendPolicy(Registry.is("debugger.step.resumes.one.thread") ? EventRequest.SUSPEND_EVENT_THREAD
+                                                                                   : suspendContext.getSuspendPolicy());
 
       if (hint != null) {
         //noinspection HardCodedStringLiteral
@@ -1464,7 +1466,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
     }
   }
 
-  private class StepOutCommand extends ResumeCommand {
+  private class StepOutCommand extends StepCommand {
     private final int myStepSize;
 
     public StepOutCommand(SuspendContextImpl suspendContext, int stepSize) {
@@ -1489,7 +1491,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
     }
   }
 
-  private class StepIntoCommand extends ResumeCommand {
+  private class StepIntoCommand extends StepCommand {
     private final boolean myForcedIgnoreFilters;
     private final MethodFilter mySmartStepFilter;
     @Nullable
@@ -1536,7 +1538,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
     }
   }
 
-  private class StepOverCommand extends ResumeCommand {
+  private class StepOverCommand extends StepCommand {
     private final boolean myIsIgnoreBreakpoints;
     private final int myStepSize;
 
@@ -1574,7 +1576,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
     }
   }
 
-  private class RunToCursorCommand extends ResumeCommand {
+  private class RunToCursorCommand extends StepCommand {
     private final RunToCursorBreakpoint myRunToCursorBreakpoint;
     private final boolean myIgnoreBreakpoints;
 
@@ -1622,9 +1624,27 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
     }
   }
 
-  public abstract class ResumeCommand extends SuspendContextCommandImpl {
+  private abstract class StepCommand extends ResumeCommand {
+    public StepCommand(SuspendContextImpl suspendContext) {
+      super(suspendContext);
+    }
 
-    private final ThreadReferenceProxyImpl myContextThread;
+    @Override
+    protected void resumeAction() {
+      SuspendContextImpl context = getSuspendContext();
+      if (context != null
+          && Registry.is("debugger.step.resumes.one.thread")
+          && context.getSuspendPolicy() == EventRequest.SUSPEND_ALL) {
+        getSuspendManager().resumeThread(context, myContextThread);
+      }
+      else {
+        super.resumeAction();
+      }
+    }
+  }
+
+  public abstract class ResumeCommand extends SuspendContextCommandImpl {
+    protected final ThreadReferenceProxyImpl myContextThread;
 
     public ResumeCommand(SuspendContextImpl suspendContext) {
       super(suspendContext);
@@ -1640,10 +1660,14 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
     @Override
     public void contextAction() {
       showStatusText(DebuggerBundle.message("status.process.resumed"));
-      getSuspendManager().resume(getSuspendContext());
+      resumeAction();
       myDebugProcessDispatcher.getMulticaster().resumed(getSuspendContext());
     }
 
+    protected void resumeAction() {
+      getSuspendManager().resume(getSuspendContext());
+    }
+
     public ThreadReferenceProxyImpl getContextThread() {
       return myContextThread;
     }
index 0717168a41c8504b9f448e8d05afb87cdc882bf3..da2c8a1f3a0866fe29433bb0cc04518e59c6c7f4 100644 (file)
@@ -274,7 +274,7 @@ public class SuspendManagerImpl implements SuspendManager {
 
   @Override
   public void resumeThread(SuspendContextImpl context, ThreadReferenceProxyImpl thread) {
-    LOG.assertTrue(thread != context.getThread(), "Use resume() instead of resuming breakpoint thread");
+    //LOG.assertTrue(thread != context.getThread(), "Use resume() instead of resuming breakpoint thread");
     LOG.assertTrue(!context.isExplicitlyResumed(thread));
 
     if(context.myResumedThreads == null) {
index ddbd89d3f95481f0944f5e6d2c362ab136891b75..f275df3a65063df6f7280e6183131ddb133b4816 100644 (file)
@@ -194,6 +194,7 @@ debugger.batch.evaluation=false
 debugger.compiling.evaluator=true
 debugger.watches.in.variables=false
 debugger.auto.fetch.icons=true
+debugger.step.resumes.one.thread=false
 
 analyze.exceptions.on.the.fly=false
 analyze.exceptions.on.the.fly.description=Automatically analyze clipboard on frame activation,\