diff --git a/python/pydevSrc/com/jetbrains/python/debugger/IPyDebugProcess.java b/python/pydevSrc/com/jetbrains/python/debugger/IPyDebugProcess.java index d9dfa9c57ae9..82155bacd88f 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/IPyDebugProcess.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/IPyDebugProcess.java @@ -35,5 +35,7 @@ public interface IPyDebugProcess extends PyFrameAccessor { void suspendAllOtherThreads(PyThreadInfo thread); + boolean isSuspendedOnAllThreadsPolicy(); + XDebugSession getSession(); } diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java index fac6d5eccc20..7b15821aef8b 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java @@ -572,6 +572,11 @@ public class RemoteDebugger implements ProcessDebugger { final PyThreadInfo thread = parseThreadEvent(frame); if (!thread.isPydevThread()) { // ignore pydevd threads myThreads.put(thread.getId(), thread); + if (myDebugProcess.getSession().isSuspended() && myDebugProcess.isSuspendedOnAllThreadsPolicy()) { + // Sometimes the notification about new threads may come slow from the Python side. We should check if + // the current session is suspended in the "Suspend all threads" mode and suspend new thread, which hasn't been suspended + suspendThread(thread.getId()); + } } break; } diff --git a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java index 5c5560ecbacc..ea7c3afccd9c 100644 --- a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java +++ b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java @@ -501,9 +501,38 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr } public void suspendAllOtherThreads(PyThreadInfo thread) { - if (thread.getStopReason() == AbstractCommand.SET_BREAKPOINT) { // add check for breakpoint setting - myDebugger.suspendOtherThreads(thread); + myDebugger.suspendOtherThreads(thread); + } + + /** + * Check if there is the thread suspended on the breakpoint with "Suspend all" policy + * + * @return true if this thread exists + */ + @Override + public boolean isSuspendedOnAllThreadsPolicy() { + if (getSession().isSuspended()) { + for (PyThreadInfo threadInfo : getThreads()) { + final List frames = threadInfo.getFrames(); + if ((threadInfo.getState() == PyThreadInfo.State.SUSPENDED) && (frames != null)) { + XBreakpoint breakpoint = null; + if (threadInfo.isStopOnBreakpoint()) { + final PySourcePosition position = frames.get(0).getPosition(); + breakpoint = myRegisteredBreakpoints.get(position); + } + else if (threadInfo.isExceptionBreak()) { + String exceptionName = threadInfo.getMessage(); + if (exceptionName != null) { + breakpoint = myRegisteredExceptionBreakpoints.get(exceptionName); + } + } + if ((breakpoint != null) && (breakpoint.getSuspendPolicy() == SuspendPolicy.ALL)) { + return true; + } + } + } } + return false; } private void passToAllThreads(final ResumeOrStepCommand.Mode mode) {