Show different error message when thread is waiting to stop after sleep

This commit is contained in:
Aleksandr Eliseev
2025-12-04 12:25:21 +03:00
parent 55b11b468d
commit 9d9dd9d028
2 changed files with 42 additions and 4 deletions

View File

@@ -838,6 +838,7 @@ debugger.stack.frame.return.values=Return Values
debugger.stack.frame.frame.not.available=<frame not available>
debugger.stack.frame.unable.to.display.frame.variables=Unable to display frame variables
debugger.stack.frames.not.available.in.non.suspended.state=Frames not available in non-suspended state
debugger.stack.frames.thread.is.sleeping.now.will.be.stopped.after.end.of.sleep=Thread is sleeping now, will be stopped after end of sleep
debugger.test.failed.caption=Test failed
debugger.error.in.test.setup.or.teardown.caption=Error in test set up or tear down
debugger.remote.port.out.of.boundaries=The port number is out of boundaries

View File

@@ -8,13 +8,31 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.*;
public class PyExecutionStack extends XExecutionStack {
private static final String IS_ON_SLEEP_FUNCTION_NAME = "__OPENIDE_INTERNAL_is_on_sleep";
private static final String IS_ON_SLEEP_FUNCTION_DEFINITION = """
def %s(thread_name):
try:
import sys
import threading
[my_native_id, *_] = [t.native_id for t in threading.enumerate() if t.name == thread_name] + [None]
if not my_native_id:
return False
frame = sys._current_frames()[my_native_id]
if not frame:
return False
filename = frame.f_code.co_filename
lineno = frame.f_lineno
with open(filename, 'r') as f:
return 'sleep' in f.readlines()[lineno - 1]
except BaseException:
return False
""".formatted(IS_ON_SLEEP_FUNCTION_NAME);
private final PyDebugProcess myDebugProcess;
private final PyThreadInfo myThreadInfo;
private PyStackFrame myTopFrame;
@@ -45,7 +63,26 @@ public class PyExecutionStack extends XExecutionStack {
@Override
public void computeStackFrames(int firstFrameIndex, XStackFrameContainer container) {
if (myThreadInfo.getState() != PyThreadInfo.State.SUSPENDED) {
container.errorOccurred(PyBundle.message("debugger.stack.frames.not.available.in.non.suspended.state"));
boolean isWaitingToStop = false;
if (myDebugProcess.isSuspendedOnAllThreadsPolicy()) {
try {
// Define function
myDebugProcess.evaluate(IS_ON_SLEEP_FUNCTION_DEFINITION, true, false);
// Call function
var isOnSleep = myDebugProcess.evaluate(IS_ON_SLEEP_FUNCTION_NAME + "('" + myThreadInfo.getName() + "')", false, false);
isWaitingToStop = Objects.equals(isOnSleep.myValue, "True");
// Delete function
myDebugProcess.evaluate("del " + IS_ON_SLEEP_FUNCTION_NAME, true, true);
} catch (PyDebuggerException e) {
// Ignore
}
}
if (!isWaitingToStop) {
container.errorOccurred(PyBundle.message("debugger.stack.frames.not.available.in.non.suspended.state"));
} else {
container.errorOccurred(PyBundle.message("debugger.stack.frames.thread.is.sleeping.now.will.be.stopped.after.end.of.sleep"));
}
return;
}