mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 11:50:54 +07:00
added stdout and stderr redirection in remote debug mode
This commit is contained in:
0
python/helpers/pydev/__init__.py
Normal file
0
python/helpers/pydev/__init__.py
Normal file
@@ -87,6 +87,7 @@ if IS_PY3K:
|
||||
connected = False
|
||||
bufferStdOutToServer = False
|
||||
bufferStdErrToServer = False
|
||||
remote = False
|
||||
|
||||
PyDBUseLocks = True
|
||||
|
||||
@@ -599,7 +600,9 @@ class PyDB:
|
||||
elif cmd_id == CMD_CONSOLE_EXEC:
|
||||
#command to exec expression in console, in case expression is only partially valid 'False' is returned
|
||||
#text is: thread\tstackframe\tLOCAL\texpression
|
||||
|
||||
thread_id, frame_id, scope, expression = text.split('\t', 3)
|
||||
|
||||
int_cmd = InternalConsoleExec(seq, thread_id, frame_id, expression)
|
||||
self.postInternalCommand(int_cmd, thread_id)
|
||||
|
||||
@@ -997,11 +1000,14 @@ def settrace(host='localhost', stdoutToServer=False, stderrToServer=False, port=
|
||||
@param suspend: whether a breakpoint should be emulated as soon as this function is called.
|
||||
@param trace_only_current_thread: determines if only the current thread will be traced or all future threads will also have the tracing enabled.
|
||||
'''
|
||||
|
||||
|
||||
global remote
|
||||
global connected
|
||||
global bufferStdOutToServer
|
||||
global bufferStdErrToServer
|
||||
|
||||
|
||||
remote = True
|
||||
|
||||
if not connected :
|
||||
connected = True
|
||||
bufferStdOutToServer = stdoutToServer
|
||||
|
||||
@@ -130,7 +130,6 @@ class PyDBFrame:
|
||||
return self.trace_dispatch
|
||||
|
||||
except:
|
||||
traceback.print_exc()
|
||||
raise
|
||||
|
||||
#step handling. We stop when we hit the right frame
|
||||
|
||||
@@ -11,6 +11,9 @@ class IORedirector:
|
||||
r.write(s)
|
||||
except:
|
||||
pass
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
class IOBuf:
|
||||
'''This class works as a replacement for stdio and stderr.
|
||||
@@ -28,4 +31,5 @@ class IOBuf:
|
||||
|
||||
def write(self, s):
|
||||
self.buflist.append(s)
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.jetbrains.python.debugger;
|
||||
|
||||
import com.intellij.execution.ui.ConsoleViewContentType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -19,4 +21,6 @@ public interface IPyDebugProcess {
|
||||
void threadResumed(PyThreadInfo thread);
|
||||
|
||||
PyDebugValue evaluate(String expression, boolean exec, boolean doTrunc) throws PyDebuggerException;
|
||||
|
||||
void printToConsole(String text, ConsoleViewContentType contentType);
|
||||
}
|
||||
|
||||
22
python/pydevSrc/com/jetbrains/python/debugger/PyIo.java
Normal file
22
python/pydevSrc/com/jetbrains/python/debugger/PyIo.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package com.jetbrains.python.debugger;
|
||||
|
||||
/**
|
||||
* @author traff
|
||||
*/
|
||||
public class PyIo {
|
||||
private final String text;
|
||||
private final int ctx;
|
||||
|
||||
public PyIo(String text, int ctx) {
|
||||
this.text = text;
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public int getCtx() {
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ public abstract class AbstractCommand {
|
||||
public static final int EVALUATE = 113;
|
||||
public static final int GET_FRAME = 114;
|
||||
public static final int EXECUTE = 115;
|
||||
public static final int WRITE_TO_CONSOLE = 116;
|
||||
public static final int CHANGE_VARIABLE = 117;
|
||||
public static final int GET_COMPLETIONS = 120;
|
||||
public static final int CONSOLE_EXEC = 121;
|
||||
@@ -75,6 +76,10 @@ public abstract class AbstractCommand {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isWriteToConsole(final int command) {
|
||||
return command == WRITE_TO_CONSOLE;
|
||||
}
|
||||
|
||||
protected static class Payload {
|
||||
private final StringBuilder myBuilder = new StringBuilder();
|
||||
private static final char SEPARATOR = '\t';
|
||||
|
||||
@@ -14,7 +14,8 @@ import java.util.List;
|
||||
|
||||
public class ProtocolParser {
|
||||
|
||||
private ProtocolParser() { }
|
||||
private ProtocolParser() {
|
||||
}
|
||||
|
||||
public static String decode(final String value) throws PyDebuggerException {
|
||||
try {
|
||||
@@ -29,6 +30,17 @@ public class ProtocolParser {
|
||||
return StringUtil.replace(expression, "\n", "@LINE@");
|
||||
}
|
||||
|
||||
public static PyIo parseIo(final String text) throws PyDebuggerException {
|
||||
final XppReader reader = openReader(text, true);
|
||||
reader.moveDown();
|
||||
if (!"io".equals(reader.getNodeName())) {
|
||||
throw new PyDebuggerException("Expected <io>, found " + reader.getNodeName());
|
||||
}
|
||||
final String s = readString(reader, "s", "");
|
||||
final int ctx = readInt(reader, "ctx", 1);
|
||||
return new PyIo(s, ctx);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PyThreadInfo parseThread(final String text, final PyPositionConverter positionConverter) throws PyDebuggerException {
|
||||
final XppReader reader = openReader(text, true);
|
||||
@@ -58,10 +70,10 @@ public class ProtocolParser {
|
||||
@NotNull
|
||||
public static String getThreadId(@NotNull String payload) {
|
||||
return payload.split("\t")[0];
|
||||
}
|
||||
}
|
||||
|
||||
private static PyStackFrameInfo parseFrame(final XppReader reader, final String threadId, final PyPositionConverter positionConverter)
|
||||
throws PyDebuggerException {
|
||||
throws PyDebuggerException {
|
||||
if (!"frame".equals(reader.getNodeName())) {
|
||||
throw new PyDebuggerException("Expected <frame>, found " + reader.getNodeName());
|
||||
}
|
||||
@@ -168,5 +180,4 @@ public class ProtocolParser {
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,13 +5,11 @@
|
||||
*/
|
||||
package com.jetbrains.python.debugger.pydev;
|
||||
|
||||
import com.intellij.execution.ui.ConsoleViewContentType;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.jetbrains.python.debugger.IPyDebugProcess;
|
||||
import com.jetbrains.python.debugger.PyDebugValue;
|
||||
import com.jetbrains.python.debugger.PyDebuggerException;
|
||||
import com.jetbrains.python.debugger.PyThreadInfo;
|
||||
import com.jetbrains.python.debugger.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -268,6 +266,10 @@ public class RemoteDebugger {
|
||||
os.write('\n');
|
||||
os.flush();
|
||||
}
|
||||
catch (SocketException se) {
|
||||
LOG.error(se);
|
||||
disconnect();
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
@@ -338,6 +340,9 @@ public class RemoteDebugger {
|
||||
if (AbstractThreadCommand.isThreadCommand(frame.getCommand())) {
|
||||
processThreadEvent(frame);
|
||||
}
|
||||
else if (AbstractCommand.isWriteToConsole(frame.getCommand())) {
|
||||
writeToConsole(parseIoEvent(frame));
|
||||
}
|
||||
else {
|
||||
placeResponse(frame.getSequence(), frame);
|
||||
}
|
||||
@@ -390,6 +395,10 @@ public class RemoteDebugger {
|
||||
}
|
||||
}
|
||||
|
||||
private PyIo parseIoEvent(ProtocolFrame frame) throws PyDebuggerException {
|
||||
return ProtocolParser.parseIo(frame.getPayload());
|
||||
}
|
||||
|
||||
private PyThreadInfo parseThreadEvent(ProtocolFrame frame) throws PyDebuggerException {
|
||||
return ProtocolParser.parseThread(frame.getPayload(), myDebugProcess.getPositionConverter());
|
||||
}
|
||||
@@ -403,6 +412,17 @@ public class RemoteDebugger {
|
||||
}
|
||||
}
|
||||
|
||||
private void writeToConsole(PyIo io) {
|
||||
ConsoleViewContentType contentType;
|
||||
if (io.getCtx() == 2) {
|
||||
contentType = ConsoleViewContentType.ERROR_OUTPUT;
|
||||
}
|
||||
else {
|
||||
contentType = ConsoleViewContentType.NORMAL_OUTPUT;
|
||||
}
|
||||
myDebugProcess.printToConsole(io.getText(), contentType);
|
||||
}
|
||||
|
||||
|
||||
private static class TempVarsHolder {
|
||||
private final Map<String, Map<String, Set<String>>> myData = new HashMap<String, Map<String, Set<String>>>();
|
||||
|
||||
@@ -139,11 +139,11 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
|
||||
|
||||
private void handshake() throws PyDebuggerException {
|
||||
final String remoteVersion = myDebugger.handshake();
|
||||
printToConsole("Connected to pydevd (version " + remoteVersion + ")\n");
|
||||
printToConsole("Connected to pydevd (version " + remoteVersion + ")\n", ConsoleViewContentType.SYSTEM_OUTPUT);
|
||||
}
|
||||
|
||||
protected void printToConsole(String text) {
|
||||
((ConsoleView)myExecutionConsole).print(text, ConsoleViewContentType.SYSTEM_OUTPUT);
|
||||
public void printToConsole(String text, ConsoleViewContentType contentType) {
|
||||
((ConsoleView)myExecutionConsole).print(text, contentType);
|
||||
}
|
||||
|
||||
private void registerBreakpoints() {
|
||||
@@ -394,13 +394,12 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
|
||||
|
||||
@Override
|
||||
public void processTerminated(ProcessEvent event) {
|
||||
|
||||
myClosing = true;
|
||||
myDebugger.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processWillTerminate(ProcessEvent event, boolean willBeDestroyed) {
|
||||
myClosing = true;
|
||||
myDebugger.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,7 +20,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class PythonRunner extends DefaultProgramRunner {
|
||||
|
||||
@NotNull
|
||||
public String getRunnerId() {
|
||||
public String getRunnerId() {
|
||||
return "PythonRunner";
|
||||
}
|
||||
|
||||
@@ -35,8 +35,7 @@ public class PythonRunner extends DefaultProgramRunner {
|
||||
RunProfileState state,
|
||||
RunContentDescriptor contentToReuse,
|
||||
ExecutionEnvironment env
|
||||
) throws ExecutionException
|
||||
{
|
||||
) throws ExecutionException {
|
||||
FileDocumentManager.getInstance().saveAllDocuments();
|
||||
|
||||
ExecutionResult executionResult;
|
||||
@@ -44,7 +43,9 @@ public class PythonRunner extends DefaultProgramRunner {
|
||||
if (state instanceof PythonCommandLineState && profile instanceof CommandLinePatcher) {
|
||||
executionResult = ((PythonCommandLineState)state).execute(executor, (CommandLinePatcher)profile);
|
||||
}
|
||||
else executionResult = state.execute(executor, this);
|
||||
else {
|
||||
executionResult = state.execute(executor, this);
|
||||
}
|
||||
if (executionResult == null) return null;
|
||||
|
||||
final RunContentBuilder contentBuilder = new RunContentBuilder(project, this, executor);
|
||||
|
||||
Reference in New Issue
Block a user