From 64117a08a48fcf4fba86b3d58fe49efa800700e2 Mon Sep 17 00:00:00 2001 From: Elizaveta Shashkova Date: Thu, 26 May 2016 19:27:50 +0300 Subject: [PATCH] Suspend new threads if the current session is suspended in "All" suspend policy (PY-2431) 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. --- .../python/debugger/IPyDebugProcess.java | 2 ++ .../python/debugger/pydev/RemoteDebugger.java | 5 +++ .../python/debugger/PyDebugProcess.java | 33 +++++++++++++++++-- 3 files changed, 38 insertions(+), 2 deletions(-) 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) {