Compare commits
18 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
53797697c3 | |
|
|
11f5dc4e37 | |
|
|
3064311546 | |
|
|
427b98b105 | |
|
|
27b41ae3e2 | |
|
|
162f6b1e2e | |
|
|
139640fdeb | |
|
|
0b64caf0a5 | |
|
|
a385ecb04a | |
|
|
3e82598c8d | |
|
|
23b579850d | |
|
|
4b937e7f86 | |
|
|
b3d54ffac3 | |
|
|
ab38aff6c7 | |
|
|
165349cc5a | |
|
|
cf2634aa55 | |
|
|
c15dc02c38 | |
|
|
5e243efef4 |
|
|
@ -1 +1,3 @@
|
|||
venv/
|
||||
*.pyc
|
||||
__pycache__/
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.8 (LSICCDS_server)" jdkType="Python SDK" />
|
||||
<orderEntry type="jdk" jdkName="Python 3.8 (2)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="PyDocumentationSettings">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (LSICCDS_server)" project-jdk-type="Python SDK" />
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (2)" project-jdk-type="Python SDK" />
|
||||
<component name="PyCharmProfessionalAdvertiser">
|
||||
<option name="shown" value="true" />
|
||||
</component>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
7
b.py
7
b.py
|
|
@ -1,7 +0,0 @@
|
|||
print("b")
|
||||
|
||||
def test():
|
||||
print("bbb")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("bb")
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
import json
|
||||
|
||||
import log
|
||||
import time
|
||||
import subprocess
|
||||
from flask import Flask
|
||||
from flask import request
|
||||
from mygdbcontroller import MyGdbController
|
||||
from pygdbmi.gdbcontroller import NoGdbProcessError
|
||||
|
||||
gdbmi = None
|
||||
app = Flask(__name__)
|
||||
|
||||
expression_list = []
|
||||
|
||||
|
||||
def request_interceptor(request):
|
||||
# Super bad practice.
|
||||
request.args = request.args.to_dict()
|
||||
command = request.args.get("command")
|
||||
request.args["original_command"] = command
|
||||
|
||||
if command.startswith("add-expression"):
|
||||
expression = command.split(" ", 1)[1]
|
||||
expression = expression.strip()
|
||||
expression_list.append(expression)
|
||||
return get_expressions(command)
|
||||
elif command.startswith("remove-expression"):
|
||||
expression = command.split(" ", 1)[1]
|
||||
expression = expression.strip()
|
||||
if expression in expression_list:
|
||||
expression_list.remove(expression)
|
||||
return get_expressions(command)
|
||||
elif "get-expressions" in command:
|
||||
expression_dict = {}
|
||||
for expression in expression_list:
|
||||
try:
|
||||
command = '-data-evaluate-expression "{}"'.format(expression)
|
||||
response = gdbmi.write(command, timeout_sec=3)
|
||||
value = ""
|
||||
for line in response:
|
||||
if (
|
||||
line["type"] != "result"
|
||||
or line["stream"] != "stdout"
|
||||
or "payload" not in line
|
||||
):
|
||||
continue
|
||||
if "value" in line["payload"]:
|
||||
value = line["payload"]["value"]
|
||||
break
|
||||
elif "msg" in line["payload"]:
|
||||
value = line["payload"]["msg"]
|
||||
break
|
||||
except Exception as e:
|
||||
value = "Unable to retrieve expression's value."
|
||||
log.error(e)
|
||||
expression_dict[expression] = value
|
||||
return expression_dict
|
||||
|
||||
|
||||
def response_interceptor(request, response):
|
||||
return response
|
||||
|
||||
|
||||
def get_expressions(command):
|
||||
expression_dict = {}
|
||||
for expression in expression_list:
|
||||
try:
|
||||
command = '-data-evaluate-expression "{}"'.format(expression)
|
||||
response = gdbmi.write(command, timeout_sec=3)
|
||||
value = ""
|
||||
for line in response:
|
||||
if (
|
||||
line["type"] != "result"
|
||||
or line["stream"] != "stdout"
|
||||
or "payload" not in line
|
||||
):
|
||||
continue
|
||||
if "value" in line["payload"]:
|
||||
value = line["payload"]["value"]
|
||||
break
|
||||
elif "msg" in line["payload"]:
|
||||
value = line["payload"]["msg"]
|
||||
break
|
||||
except Exception as e:
|
||||
value = "Unable to retrieve expression's value."
|
||||
log.error(e)
|
||||
expression_dict[expression] = value
|
||||
return expression_dict
|
||||
|
||||
|
||||
@app.route("/compile")
|
||||
def compile():
|
||||
language = request.args.get("language")
|
||||
command = request.args.get("command")
|
||||
command_list = command.split(",")
|
||||
if language is None or language == "c":
|
||||
compile_command = ["gcc", "-g", "-o", "myProgram.out"] + command_list
|
||||
else:
|
||||
compile_command = ["g++", "-g", "-std=c++11", "-lstdc++", "-o", "myProgram.out"] + command_list
|
||||
try:
|
||||
result = subprocess.run(compile_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, check=True)
|
||||
output = result.stdout + result.stderr
|
||||
return output
|
||||
except subprocess.CalledProcessError as e:
|
||||
return "Compilation Error:\n" + e.stderr
|
||||
|
||||
@app.route("/run_command")
|
||||
def run_command():
|
||||
response = request_interceptor(request)
|
||||
if response is not None:
|
||||
log.info("Response given through custom interceptor.")
|
||||
return json.dumps(response)
|
||||
|
||||
command = request.args.get("command")
|
||||
gdbmi.write(command, read_response=False)
|
||||
time.sleep(1)
|
||||
return get_responses()
|
||||
|
||||
|
||||
@app.route("/get_responses")
|
||||
def get_responses():
|
||||
try:
|
||||
response = gdbmi.get_gdb_response(
|
||||
timeout_sec=0, raise_error_on_timeout=False
|
||||
)
|
||||
|
||||
except NoGdbProcessError as e:
|
||||
response = {
|
||||
"message": "stopped",
|
||||
"payload": {
|
||||
"reason": "exception",
|
||||
"msg": str(e),
|
||||
},
|
||||
}
|
||||
|
||||
return {'response': response}
|
||||
|
||||
|
||||
def main():
|
||||
global gdbmi
|
||||
input_file = open('input.txt', 'r')
|
||||
output_file = open('output.txt', 'w')
|
||||
gdbmi = MyGdbController(gdb_args=["--quiet", "--interpreter=mi2"], input_file=input_file, output_file=output_file)
|
||||
app.run(host="0.0.0.0", port=80)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
//#include <bits/stdc++.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
int main(){
|
||||
int arr[] = {1,2,3};
|
||||
printf(" 对面的女孩看过来!\n");
|
||||
string s = "1234";
|
||||
string s2 = "q";
|
||||
int a = s[0]-'0';
|
||||
int b = s[1]-'0';
|
||||
int c = s[2]-'0';
|
||||
int d = s[3]-'0';
|
||||
|
||||
int e = s2[4]-'0';
|
||||
|
||||
printf(" %d-%d-%d-%d\n",a,b,c,d);
|
||||
printf(" %d\n",e);
|
||||
printf(" %d\n",arr[d]);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.apple.xcode.dsym.test</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>dSYM</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
break user_code/prog_joined.py:13continuebreak user_code/prog_joined.py:15nextstepnextnextwherenextwherebreak b.py:1continuecontinuebreak b.py:1nextnextnextnextnextbreak b.py:1continuebreak b.py:4break b.py:7continuenextnextnextnextnextnextbreak b.py:6break b.py:7continuenextnextcontinuecontinuebreak b.py:1break b.py:7continuecontinue
|
||||
break user_code/python_test/test.py:3continuenextnextnextnextnextbreak user_code/python_test/test.py:3continuenextnextnextnextnextbreak user_code/python_test/test.py:3continuenextnextnextnextnextbreak user_code/python_test/test.py:3continuenextnextnextnextnextbreak user_code/python_test/test.py:3nextnextnextreturnclear user_code/python_test/test.py:3continuebreak user_code/python_test/test.py:3nextcontinuebreak user_code/python_test/test.py:3continuecontinuenextreturnreturncontinuebreak user_code/python_test/test.py:3break user_code/python_test/test.py:5continuebreak user_code/python_test/test.py:3break user_code/python_test/test.py:5break user_code/python_test/test.py:3nextnextbreak user_code/python_test/test.py:6break user_code/python_test/test.py:3break user_code/python_test/test.py:6continuebreak user_code/python_test/test.py:3break user_code/python_test/test.py:6continuenextnextcontinuebreak user_code/python_test/test.py:3break user_code/python_test/test.py:35break user_code/python_test/test.py:5continuecontinuecontinuebreak user_code/python_test/test.py:5continuebreak user_code/python_test/test.py:5break user_code/python_test/test.py:7continuebreak user_code/python_test/test.py:5break user_code/python_test/test.py:7nextnextnextbreak user_code/python_test/test.py:5break user_code/python_test/test.py:7continuecontinuestepnextreturnnextbreak user_code/python_test/test.py:4break user_code/python_test/test.py:5break user_code.python_test.person.py:2break user_code.python_test.person.py:2break user_code/python_test/person.py:2continuebreak user_code/python_test/test.py:5break user_code/python_test/person.py:2nextnextcontinuebreak user_code/python_test/test.py:5break user_code/python_test/person.py:2nextbreak user_code/python_test/test.py:5break user_code/python_test/person.py:2continuebreak user_code/python_test/test.py:5continuebreak user_code/python_test/test.py:5continuebreak user_code/python_test/test.py:5break user_code/python_test/person.py:2continuebreak user_code/python_test/test.py:5break user_code/python_test/person.py:2nextcontinuebreak user_code/python_test/test.py:5break user_code/python_test/person.py:2nextnextnextnextnextcontinuebreak user_code/python_test/test.py:5break user_code/python_test/person.py:2continuebreak user_code/python_test/test.py:5break /test.py:5break test.py:5break person.py:2continuebreak python_test/test.py:4continuebreak person.py:2nextcontinuecontinuebreak person.py:2continuecontinuebreak%test.py:3break test.py:3continuecontinuecontinuebreak test.py:3nextcontinuebreak test.py:3nextcontinuebreak test.py:3nextcontinuebreak test.py:3continuebreak test.py:3nextcontinuebreak test.py:3continuecontinuebreak test.py:3nextcontinuebreak test.py:3nextcontinuebreak test.py:3nextcontinuebreak test.py:3nextcontinuebreak test.py:3continuecontinuebreak test.py:3continuecontinuebreak test.py:3break test02.py:3continuecontinuebreak test.py:3continuebreak test.py:3break test02.py:3continuecontinue
|
||||
25
console.py
25
console.py
|
|
@ -6,7 +6,6 @@ import sys
|
|||
import weakref
|
||||
from threading import Event
|
||||
from threading import RLock
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
import queue
|
||||
|
|
@ -89,37 +88,27 @@ class Console(object):
|
|||
try:
|
||||
frame_data = self._debugger.get_current_frame_data()
|
||||
except (IOError, AttributeError):
|
||||
f = open("user_code/user.out")
|
||||
out_content = f.read()
|
||||
f.close()
|
||||
frame_data = {
|
||||
"dirname": "",
|
||||
"filename": "",
|
||||
"file_listing": "No data available",
|
||||
"current_line": -1,
|
||||
"breakpoints": [],
|
||||
"breakpoints": {},
|
||||
"globals": {},
|
||||
"locals": {},
|
||||
"expressions": {},
|
||||
"exception": sys.exc_info(),
|
||||
"out": out_content,
|
||||
"is_over": True
|
||||
}
|
||||
|
||||
frame_data["console_history"] = self._console_history.contents
|
||||
frame_data["stdout"] = Path("user_code/stdout.txt").read_text().replace("""
|
||||
PYDEV DEBUGGER WARNING:
|
||||
sys.settrace() should not be used when the debugger is being used.
|
||||
This may cause the debugger to stop working correctly.
|
||||
If this is needed, please check:
|
||||
http://pydev.blogspot.com/2007/06/why-cant-pydev-debugger-work-with.html
|
||||
to see how to restore the debug tracing back correctly.
|
||||
Call Location:
|
||||
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/bdb.py", line 334, in set_trace
|
||||
sys.settrace(self.trace_dispatch)
|
||||
|
||||
""", "")
|
||||
self._frame_data.contents = frame_data
|
||||
# print("frame_data: " + str(frame_data))
|
||||
# print("data: " + data)
|
||||
if "(Pdb)" in data:
|
||||
self._output_ok.set()
|
||||
# print("释放OK琐")
|
||||
|
||||
write = writeline
|
||||
|
||||
|
|
@ -134,7 +123,7 @@ Call Location:
|
|||
|
||||
def get_frame_data(self):
|
||||
# print("f 尝试获取琐")
|
||||
self._output_ok.wait()
|
||||
self._output_ok.wait(3)
|
||||
# print("f 获取到琐")
|
||||
c = self._frame_data.contents
|
||||
return c
|
||||
|
|
|
|||
|
|
@ -9,7 +9,20 @@ class RawInputException(Exception):
|
|||
pass
|
||||
|
||||
|
||||
def raw_input_wrapper():
|
||||
class StreamStdin(object):
|
||||
def __init__(self, input_queue):
|
||||
self.input_queue = input_queue
|
||||
|
||||
def readline(self):
|
||||
if len(self.input_queue) > 0:
|
||||
return self.input_queue.pop(0)
|
||||
else:
|
||||
return ""
|
||||
|
||||
|
||||
def raw_input_wrapper(*args):
|
||||
if len(args) > 0:
|
||||
print(args[0])
|
||||
if input_queue:
|
||||
return input_queue.pop(0)
|
||||
raise RawInputException()
|
||||
|
|
@ -39,6 +52,11 @@ def override_input():
|
|||
global input_queue
|
||||
input_queue = list(file.readlines())
|
||||
|
||||
input_queue_new = []
|
||||
for val in input_queue:
|
||||
input_queue_new.append(val.replace("\n", "").strip())
|
||||
input_queue = input_queue_new
|
||||
|
||||
builtins.raw_input = raw_input_wrapper
|
||||
|
||||
if is_python3:
|
||||
|
|
@ -46,7 +64,8 @@ def override_input():
|
|||
else:
|
||||
builtins.input = python2_input_wrapper
|
||||
|
||||
sys.stdin = stream_stdin()
|
||||
stdin = StreamStdin(input_queue)
|
||||
sys.stdin = stdin
|
||||
|
||||
|
||||
class UnbufferedWrite(object):
|
||||
|
|
@ -66,5 +85,4 @@ class UnbufferedWrite(object):
|
|||
|
||||
|
||||
def get_stdout_wrapper():
|
||||
return UnbufferedWrite(open("user_code/stdout.txt", "w"))
|
||||
|
||||
return UnbufferedWrite(open("user_code/user.out", "w"))
|
||||
|
|
|
|||
20
main.htm
20
main.htm
|
|
@ -94,13 +94,13 @@
|
|||
$(function() {
|
||||
var $editor = $('#editor');
|
||||
var $debugger = $('#debugger');
|
||||
var editorText = "print(\"b\")\n" +
|
||||
"\n" +
|
||||
"def test():\n" +
|
||||
" print(\"bbb\")\n" +
|
||||
" \n" +
|
||||
"if __name__ == \"__main__\":\n" +
|
||||
" print(\"bb\")";
|
||||
var editorText = "import time\n" +
|
||||
"\n" +
|
||||
"a=input()\n" +
|
||||
"# time.sleep(5)\n" +
|
||||
"b=10\n" +
|
||||
"print('hello'+\"11\\t\")\n" +
|
||||
"print('b+10=', (b+10))";
|
||||
var currentLine = -1;
|
||||
|
||||
function updateEditor(text) {
|
||||
|
|
@ -130,7 +130,7 @@
|
|||
$locals.html(JSON.stringify(data.locals));
|
||||
// 取控制台输出
|
||||
var $console = $('#console');
|
||||
$console.html(data.stdout);
|
||||
$console.html(data.console_history);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -187,12 +187,12 @@
|
|||
|
||||
$debugger.find('#breakpoint').on('click', function() {
|
||||
var $breakLineNo = $('#breakLineNo');
|
||||
sendRequest('http://127.0.0.1:8079/run_command', {"command": "break b.py:" + $breakLineNo.val() + ""}, updateContent);
|
||||
sendRequest('http://127.0.0.1:8079/run_command', {"command": "break test.py:" + $breakLineNo.val() + ""}, updateContent);
|
||||
});
|
||||
|
||||
$debugger.find('#removebreakpoint').on('click', function() {
|
||||
var $breakLineNo = $('#breakLineNo');
|
||||
sendRequest('http://127.0.0.1:8079/run_command', {"command": "clear b.py:" + $breakLineNo.val() + ""}, updateContent);
|
||||
sendRequest('http://127.0.0.1:8079/run_command', {"command": "clear user_code/python_test/test.py:" + $breakLineNo.val() + ""}, updateContent);
|
||||
});
|
||||
|
||||
$debugger.find('#addExpression').on('click', function() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,597 @@
|
|||
"""This module defines the `GdbController` class
|
||||
which runs gdb as a subprocess and can write to it and read from it to get
|
||||
structured output.
|
||||
"""
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import select
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
from distutils.spawn import find_executable
|
||||
from typing import Any, List, IO, Optional, Union
|
||||
|
||||
from pygdbmi import gdbmiparser
|
||||
|
||||
try: # py3
|
||||
from shlex import quote
|
||||
except ImportError: # py2
|
||||
from pipes import quote
|
||||
|
||||
_FILE = Union[None, int, IO[Any]]
|
||||
PYTHON3 = sys.version_info.major == 3
|
||||
DEFAULT_GDB_TIMEOUT_SEC = 1
|
||||
DEFAULT_TIME_TO_CHECK_FOR_ADDITIONAL_OUTPUT_SEC = 0.2
|
||||
USING_WINDOWS = os.name == "nt"
|
||||
if USING_WINDOWS:
|
||||
import msvcrt
|
||||
from ctypes import windll, byref, wintypes, WinError, POINTER # type: ignore
|
||||
from ctypes.wintypes import HANDLE, DWORD, BOOL
|
||||
else:
|
||||
import fcntl
|
||||
|
||||
SIGNAL_NAME_TO_NUM = {}
|
||||
for n in dir(signal):
|
||||
if n.startswith("SIG") and "_" not in n:
|
||||
SIGNAL_NAME_TO_NUM[n.upper()] = getattr(signal, n)
|
||||
|
||||
|
||||
class NoGdbProcessError(ValueError):
|
||||
"""Raise when trying to interact with gdb subprocess, but it does not exist.
|
||||
It may have been killed and removed, or failed to initialize for some reason."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class GdbTimeoutError(ValueError):
|
||||
"""Raised when no response is recieved from gdb after the timeout has been triggered"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class MyGdbController:
|
||||
def __init__(
|
||||
self,
|
||||
gdb_path: str = "gdb",
|
||||
gdb_args: Optional[List] = None,
|
||||
time_to_check_for_additional_output_sec=DEFAULT_TIME_TO_CHECK_FOR_ADDITIONAL_OUTPUT_SEC,
|
||||
rr: bool = False,
|
||||
verbose: bool = False,
|
||||
input_file: IO[Any] = ...,
|
||||
output_file: IO[Any] = ...
|
||||
):
|
||||
"""
|
||||
Run gdb as a subprocess. Send commands and receive structured output.
|
||||
Create new object, along with a gdb subprocess
|
||||
|
||||
Args:
|
||||
gdb_path: Command to run in shell to spawn new gdb subprocess
|
||||
gdb_args: Arguments to pass to shell when spawning new gdb subprocess
|
||||
time_to_check_for_additional_output_sec: When parsing responses, wait this amout of time before exiting (exits before timeout is reached to save time). If <= 0, full timeout time is used.
|
||||
rr:: Use the `rr replay` command instead of `gdb`. See rr-project.org for more info.
|
||||
verbose: Print verbose output if True
|
||||
Returns:
|
||||
New GdbController object
|
||||
"""
|
||||
|
||||
if gdb_args is None:
|
||||
default_gdb_args = ["--nx", "--quiet", "--interpreter=mi2"]
|
||||
gdb_args = default_gdb_args
|
||||
|
||||
self.verbose = verbose
|
||||
self.abs_gdb_path = None # abs path to gdb executable
|
||||
self.cmd = [] # type: List[str]
|
||||
self.time_to_check_for_additional_output_sec = (
|
||||
time_to_check_for_additional_output_sec
|
||||
)
|
||||
self.gdb_process = None
|
||||
self.input_file = input_file
|
||||
self.output_file = output_file
|
||||
self._allow_overwrite_timeout_times = (
|
||||
self.time_to_check_for_additional_output_sec > 0
|
||||
)
|
||||
self.first = True
|
||||
|
||||
if rr:
|
||||
self.cmd = ["rr", "replay"] + gdb_args
|
||||
|
||||
else:
|
||||
if not gdb_path:
|
||||
raise ValueError("a valid path to gdb must be specified")
|
||||
|
||||
else:
|
||||
abs_gdb_path = find_executable(gdb_path)
|
||||
if abs_gdb_path is None:
|
||||
raise ValueError(
|
||||
'gdb executable could not be resolved from "%s"' % gdb_path
|
||||
)
|
||||
|
||||
else:
|
||||
self.abs_gdb_path = abs_gdb_path
|
||||
self.cmd = [self.abs_gdb_path] + gdb_args
|
||||
|
||||
self._attach_logger(verbose)
|
||||
self.spawn_new_gdb_subprocess()
|
||||
|
||||
def _attach_logger(self, verbose: bool):
|
||||
handler = logging.StreamHandler()
|
||||
handler.setFormatter(logging.Formatter("%(message)s"))
|
||||
unique_number = time.time()
|
||||
self.logger = logging.getLogger(__name__ + "." + str(unique_number))
|
||||
self.logger.propagate = False
|
||||
if verbose:
|
||||
level = logging.DEBUG
|
||||
else:
|
||||
level = logging.ERROR
|
||||
self.logger.setLevel(level)
|
||||
self.logger.addHandler(handler)
|
||||
|
||||
def get_subprocess_cmd(self):
|
||||
"""Returns the shell-escaped string used to invoke the gdb subprocess.
|
||||
This is a string that can be executed directly in a shell.
|
||||
"""
|
||||
return " ".join(quote(c) for c in self.cmd)
|
||||
|
||||
def spawn_new_gdb_subprocess(self):
|
||||
"""Spawn a new gdb subprocess with the arguments supplied to the object
|
||||
during initialization. If gdb subprocess already exists, terminate it before
|
||||
spanwing a new one.
|
||||
Return int: gdb process id
|
||||
"""
|
||||
if self.gdb_process:
|
||||
self.logger.debug(
|
||||
"Killing current gdb subprocess (pid %d)" % self.gdb_process.pid
|
||||
)
|
||||
self.exit()
|
||||
|
||||
self.logger.debug('Launching gdb: "%s"' % " ".join(self.cmd))
|
||||
self.cmd = ["stdbuf", "-oL", "-eL"] + self.cmd
|
||||
print(self.cmd)
|
||||
|
||||
# Use pipes to the standard streams
|
||||
self.gdb_process = subprocess.Popen(
|
||||
self.cmd,
|
||||
shell=False,
|
||||
stdout=subprocess.PIPE,
|
||||
stdin=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
bufsize=0,
|
||||
)
|
||||
|
||||
# self.gdb_process.stdin = self.input_file
|
||||
# self.gdb_process.stdout = self.output_file
|
||||
# self.gdb_process.stderr = self.output_file
|
||||
# self.gdb_process.wait()
|
||||
|
||||
_make_non_blocking(self.gdb_process.stdout)
|
||||
_make_non_blocking(self.gdb_process.stderr)
|
||||
|
||||
# save file numbers for use later
|
||||
self.stdout_fileno = self.gdb_process.stdout.fileno()
|
||||
self.stderr_fileno = self.gdb_process.stderr.fileno()
|
||||
self.stdin_fileno = self.gdb_process.stdin.fileno()
|
||||
|
||||
self.read_list = [self.stdout_fileno, self.stderr_fileno]
|
||||
self.write_list = [self.stdin_fileno]
|
||||
|
||||
# string buffers for unifinished gdb output
|
||||
self._incomplete_output = {"stdout": None, "stderr": None}
|
||||
|
||||
while True:
|
||||
events, _, _ = select.select(self.read_list, [], [], 0)
|
||||
flag = False
|
||||
for fileno in events:
|
||||
# new data is ready to read
|
||||
if fileno == self.stdout_fileno:
|
||||
self.gdb_process.stdout.flush()
|
||||
output = self.gdb_process.stdout.read().decode()
|
||||
flag = ("(gdb)" in output)
|
||||
if flag:
|
||||
break
|
||||
|
||||
return self.gdb_process.pid
|
||||
|
||||
def verify_valid_gdb_subprocess(self):
|
||||
|
||||
"""Verify there is a process object, and that it is still running.
|
||||
Raise NoGdbProcessError if either of the above are not true."""
|
||||
if not self.gdb_process:
|
||||
raise NoGdbProcessError("gdb process is not attached")
|
||||
|
||||
elif self.gdb_process.poll() is not None:
|
||||
raise NoGdbProcessError(
|
||||
"gdb process has already finished with return code: %s"
|
||||
% str(self.gdb_process.poll())
|
||||
)
|
||||
|
||||
def write(
|
||||
self,
|
||||
mi_cmd_to_write: Union[str, List[str]],
|
||||
timeout_sec=DEFAULT_GDB_TIMEOUT_SEC,
|
||||
raise_error_on_timeout: bool = True,
|
||||
read_response: bool = True,
|
||||
):
|
||||
"""Write to gdb process. Block while parsing responses from gdb for a maximum of timeout_sec.
|
||||
|
||||
Args:
|
||||
mi_cmd_to_write: String to write to gdb. If list, it is joined by newlines.
|
||||
timeout_sec: Maximum number of seconds to wait for response before exiting. Must be >= 0.
|
||||
raise_error_on_timeout: If read_response is True, raise error if no response is received
|
||||
read_response: Block and read response. If there is a separate thread running,
|
||||
this can be false, and the reading thread read the output.
|
||||
Returns:
|
||||
List of parsed gdb responses if read_response is True, otherwise []
|
||||
Raises:
|
||||
NoGdbProcessError: if there is no gdb subprocess running
|
||||
TypeError: if mi_cmd_to_write is not valid
|
||||
"""
|
||||
self.verify_valid_gdb_subprocess()
|
||||
if timeout_sec < 0:
|
||||
self.logger.warning("timeout_sec was negative, replacing with 0")
|
||||
timeout_sec = 0
|
||||
|
||||
# Ensure proper type of the mi command
|
||||
if isinstance(mi_cmd_to_write, str):
|
||||
mi_cmd_to_write_str = mi_cmd_to_write
|
||||
elif isinstance(mi_cmd_to_write, list):
|
||||
mi_cmd_to_write_str = "\n".join(mi_cmd_to_write)
|
||||
else:
|
||||
raise TypeError(
|
||||
"The gdb mi command must a be str or list. Got "
|
||||
+ str(type(mi_cmd_to_write))
|
||||
)
|
||||
|
||||
self.logger.debug("writing: %s", mi_cmd_to_write)
|
||||
|
||||
if not mi_cmd_to_write_str.endswith("\n"):
|
||||
mi_cmd_to_write_nl = mi_cmd_to_write_str + "\n"
|
||||
else:
|
||||
mi_cmd_to_write_nl = mi_cmd_to_write_str
|
||||
|
||||
if USING_WINDOWS:
|
||||
# select not implemented in windows for pipes
|
||||
# assume it's always ready
|
||||
outputready = [self.stdin_fileno]
|
||||
else:
|
||||
_, outputready, _ = select.select([], self.write_list, [], timeout_sec)
|
||||
for fileno in outputready:
|
||||
if fileno == self.stdin_fileno:
|
||||
print("用户输入-------", mi_cmd_to_write_nl.encode())
|
||||
# ready to write
|
||||
self.gdb_process.stdin.write( # type: ignore
|
||||
mi_cmd_to_write_nl.encode()
|
||||
)
|
||||
# don't forget to flush for Python3, otherwise gdb won't realize there is data
|
||||
# to evaluate, and we won't get a response
|
||||
self.gdb_process.stdin.flush() # type: ignore
|
||||
else:
|
||||
self.logger.error("got unexpected fileno %d" % fileno)
|
||||
|
||||
if read_response is True:
|
||||
return self.get_gdb_response(
|
||||
timeout_sec=timeout_sec, raise_error_on_timeout=raise_error_on_timeout
|
||||
)
|
||||
|
||||
else:
|
||||
return []
|
||||
|
||||
def get_gdb_response(
|
||||
self, timeout_sec: float = DEFAULT_GDB_TIMEOUT_SEC, raise_error_on_timeout=True
|
||||
):
|
||||
"""Get response from GDB, and block while doing so. If GDB does not have any response ready to be read
|
||||
by timeout_sec, an exception is raised.
|
||||
|
||||
Args:
|
||||
timeout_sec: Maximum time to wait for reponse. Must be >= 0. Will return after
|
||||
raise_error_on_timeout: Whether an exception should be raised if no response was found after timeout_sec
|
||||
|
||||
Returns:
|
||||
List of parsed GDB responses, returned from gdbmiparser.parse_response, with the
|
||||
additional key 'stream' which is either 'stdout' or 'stderr'
|
||||
|
||||
Raises:
|
||||
GdbTimeoutError: if response is not received within timeout_sec
|
||||
ValueError: if select returned unexpected file number
|
||||
NoGdbProcessError: if there is no gdb subprocess running
|
||||
"""
|
||||
|
||||
self.verify_valid_gdb_subprocess()
|
||||
if timeout_sec < 0:
|
||||
self.logger.warning("timeout_sec was negative, replacing with 0")
|
||||
timeout_sec = 0
|
||||
|
||||
if USING_WINDOWS:
|
||||
retval = self._get_responses_windows(timeout_sec)
|
||||
else:
|
||||
retval = self._get_responses_unix(timeout_sec)
|
||||
|
||||
if not retval and raise_error_on_timeout:
|
||||
raise GdbTimeoutError(
|
||||
"Did not get response from gdb after %s seconds" % timeout_sec
|
||||
)
|
||||
|
||||
else:
|
||||
return retval
|
||||
|
||||
def _get_responses_windows(self, timeout_sec):
|
||||
"""Get responses on windows. Assume no support for select and use a while loop."""
|
||||
timeout_time_sec = time.time() + timeout_sec
|
||||
responses = []
|
||||
while True:
|
||||
try:
|
||||
self.gdb_process.stdout.flush()
|
||||
if PYTHON3:
|
||||
raw_output = self.gdb_process.stdout.readline().replace(
|
||||
b"\r", b"\n"
|
||||
)
|
||||
else:
|
||||
raw_output = self.gdb_process.stdout.read().replace(b"\r", b"\n")
|
||||
responses += self._get_responses_list(raw_output, "stdout")
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
try:
|
||||
self.gdb_process.stderr.flush()
|
||||
if PYTHON3:
|
||||
raw_output = self.gdb_process.stderr.readline().replace(
|
||||
b"\r", b"\n"
|
||||
)
|
||||
else:
|
||||
raw_output = self.gdb_process.stderr.read().replace(b"\r", b"\n")
|
||||
responses += self._get_responses_list(raw_output, "stderr")
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
if time.time() > timeout_time_sec:
|
||||
break
|
||||
|
||||
return responses
|
||||
|
||||
def _get_responses_unix(self, timeout_sec):
|
||||
"""Get responses on unix-like system. Use select to wait for output."""
|
||||
timeout_time_sec = time.time() + timeout_sec
|
||||
responses = []
|
||||
while True:
|
||||
select_timeout = timeout_time_sec - time.time()
|
||||
# I prefer to not pass a negative value to select
|
||||
if select_timeout <= 0:
|
||||
select_timeout = 0
|
||||
events, _, _ = select.select(self.read_list, [], [], select_timeout)
|
||||
responses_list = None # to avoid infinite loop if using Python 2
|
||||
try:
|
||||
for fileno in events:
|
||||
# new data is ready to read
|
||||
if fileno == self.stdout_fileno:
|
||||
self.gdb_process.stdout.flush()
|
||||
raw_output = self.gdb_process.stdout.read()
|
||||
stream = "stdout"
|
||||
|
||||
elif fileno == self.stderr_fileno:
|
||||
self.gdb_process.stderr.flush()
|
||||
continue
|
||||
raw_output = self.gdb_process.stderr.read()
|
||||
stream = "stderr"
|
||||
|
||||
else:
|
||||
raise ValueError(
|
||||
"Developer error. Got unexpected file number %d" % fileno
|
||||
)
|
||||
|
||||
response_list = list(
|
||||
filter(lambda x: x, raw_output.decode(errors="replace").split("\n"))
|
||||
) # remove blank lines
|
||||
|
||||
self.write_output(response_list)
|
||||
|
||||
if _contains_input_fun(response_list):
|
||||
self.write_input()
|
||||
time.sleep(1)
|
||||
return self.get_gdb_response(timeout_sec=0, raise_error_on_timeout=False)
|
||||
|
||||
# parse each response from gdb into a dict, and store in a list
|
||||
last_response = response_list[len(response_list) - 1]
|
||||
if "(gdb)" not in last_response:
|
||||
self.write_input()
|
||||
time.sleep(1)
|
||||
return self.get_gdb_response(timeout_sec=0, raise_error_on_timeout=False)
|
||||
|
||||
responses_list = self._get_responses_list(raw_output, stream)
|
||||
responses += responses_list
|
||||
|
||||
except IOError: # only occurs in python 2.7
|
||||
pass
|
||||
|
||||
if timeout_sec == 0: # just exit immediately
|
||||
break
|
||||
|
||||
elif responses_list and self._allow_overwrite_timeout_times:
|
||||
# update timeout time to potentially be closer to now to avoid lengthy wait times when nothing is being output by gdb
|
||||
timeout_time_sec = min(
|
||||
time.time() + self.time_to_check_for_additional_output_sec,
|
||||
timeout_time_sec,
|
||||
)
|
||||
|
||||
elif time.time() > timeout_time_sec:
|
||||
break
|
||||
|
||||
return responses
|
||||
|
||||
def _get_responses_list(self, raw_output, stream):
|
||||
"""Get parsed response list from string output
|
||||
Args:
|
||||
raw_output (unicode): gdb output to parse
|
||||
stream (str): either stdout or stderr
|
||||
"""
|
||||
responses = []
|
||||
|
||||
raw_output, self._incomplete_output[stream] = _buffer_incomplete_responses(
|
||||
raw_output, self._incomplete_output.get(stream)
|
||||
)
|
||||
|
||||
if not raw_output:
|
||||
return responses
|
||||
|
||||
response_list = list(
|
||||
filter(lambda x: x, raw_output.decode(errors="replace").split("\n"))
|
||||
) # remove blank lines
|
||||
|
||||
for response in response_list:
|
||||
if gdbmiparser.response_is_finished(response):
|
||||
pass
|
||||
else:
|
||||
parsed_response = gdbmiparser.parse_response(response)
|
||||
parsed_response["stream"] = stream
|
||||
if parsed_response["type"] != "log":
|
||||
responses.append(parsed_response)
|
||||
|
||||
return responses
|
||||
|
||||
def send_signal_to_gdb(self, signal_input):
|
||||
"""Send signal name (case insensitive) or number to gdb subprocess
|
||||
These are all valid ways to call this method:
|
||||
```
|
||||
gdbmi.send_signal_to_gdb(2)
|
||||
gdbmi.send_signal_to_gdb('sigint')
|
||||
gdbmi.send_signal_to_gdb('SIGINT')
|
||||
```
|
||||
|
||||
raises:
|
||||
ValueError: if signal_input is invalid
|
||||
NoGdbProcessError: if there is no gdb process to send a signal to
|
||||
"""
|
||||
try:
|
||||
signal = int(signal_input)
|
||||
except Exception:
|
||||
signal = SIGNAL_NAME_TO_NUM.get(signal_input.upper())
|
||||
|
||||
if not signal:
|
||||
raise ValueError(
|
||||
'Could not find signal corresponding to "%s"' % str(signal)
|
||||
)
|
||||
|
||||
if self.gdb_process:
|
||||
os.kill(self.gdb_process.pid, signal)
|
||||
else:
|
||||
raise NoGdbProcessError(
|
||||
"Cannot send signal to gdb process because no process exists."
|
||||
)
|
||||
|
||||
def interrupt_gdb(self):
|
||||
"""Send SIGINT (interrupt signal) to the gdb subprocess"""
|
||||
self.send_signal_to_gdb("SIGINT")
|
||||
|
||||
def exit(self) -> None:
|
||||
"""Terminate gdb process"""
|
||||
if self.gdb_process:
|
||||
self.gdb_process.terminate()
|
||||
self.gdb_process.communicate()
|
||||
self.gdb_process = None
|
||||
return None
|
||||
|
||||
def write_input(self):
|
||||
raw_input = self.input_file.readline()
|
||||
print("自动读入的数据为:", raw_input)
|
||||
self.gdb_process.stdin.write(raw_input.encode())
|
||||
self.gdb_process.stdin.flush()
|
||||
|
||||
def write_output(self, response_list):
|
||||
for response in response_list:
|
||||
if gdbmiparser.response_is_finished(response):
|
||||
pass
|
||||
else:
|
||||
parsed_response = gdbmiparser.parse_response(response)
|
||||
|
||||
if parsed_response["type"] == "output":
|
||||
output = parsed_response["payload"]
|
||||
self.output_file.writelines(output + "\n")
|
||||
self.output_file.flush()
|
||||
|
||||
|
||||
def _buffer_incomplete_responses(raw_output, buf):
|
||||
"""It is possible for some of gdb's output to be read before it completely finished its response.
|
||||
In that case, a partial mi response was read, which cannot be parsed into structured data.
|
||||
We want to ALWAYS parse complete mi records. To do this, we store a buffer of gdb's
|
||||
output if the output did not end in a newline.
|
||||
|
||||
Args:
|
||||
raw_output: Contents of the gdb mi output
|
||||
buf (str): Buffered gdb response from the past. This is incomplete and needs to be prepended to
|
||||
gdb's next output.
|
||||
|
||||
Returns:
|
||||
(raw_output, buf)
|
||||
"""
|
||||
|
||||
if raw_output:
|
||||
if buf:
|
||||
# concatenate buffer and new output
|
||||
raw_output = b"".join([buf, raw_output])
|
||||
buf = None
|
||||
|
||||
if b"\n" not in raw_output:
|
||||
# newline was not found, so assume output is incomplete and store in buffer
|
||||
buf = raw_output
|
||||
raw_output = None
|
||||
|
||||
elif not raw_output.endswith(b"\n"):
|
||||
# raw output doesn't end in a newline, so store everything after the last newline (if anything)
|
||||
# in the buffer, and parse everything before it
|
||||
remainder_offset = raw_output.rindex(b"\n") + 1
|
||||
buf = raw_output[remainder_offset:]
|
||||
raw_output = raw_output[:remainder_offset]
|
||||
|
||||
return (raw_output, buf)
|
||||
|
||||
|
||||
def _make_non_blocking(file_obj):
|
||||
"""make file object non-blocking
|
||||
Windows doesn't have the fcntl module, but someone on
|
||||
stack overflow supplied this code as an answer, and it works
|
||||
http://stackoverflow.com/a/34504971/2893090"""
|
||||
|
||||
if USING_WINDOWS:
|
||||
LPDWORD = POINTER(DWORD)
|
||||
PIPE_NOWAIT = wintypes.DWORD(0x00000001)
|
||||
|
||||
SetNamedPipeHandleState = windll.kernel32.SetNamedPipeHandleState
|
||||
SetNamedPipeHandleState.argtypes = [HANDLE, LPDWORD, LPDWORD, LPDWORD]
|
||||
SetNamedPipeHandleState.restype = BOOL
|
||||
|
||||
h = msvcrt.get_osfhandle(file_obj.fileno())
|
||||
|
||||
res = windll.kernel32.SetNamedPipeHandleState(h, byref(PIPE_NOWAIT), None, None)
|
||||
if res == 0:
|
||||
raise ValueError(WinError())
|
||||
|
||||
else:
|
||||
# Set the file status flag (F_SETFL) on the pipes to be non-blocking
|
||||
# so we can attempt to read from a pipe with no new data without locking
|
||||
# the program up
|
||||
fcntl.fcntl(file_obj.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
|
||||
|
||||
|
||||
'''
|
||||
判断是否包含输入函数
|
||||
'''
|
||||
|
||||
|
||||
def _contains_input_fun(response_list: list = []):
|
||||
running = False
|
||||
stop = True
|
||||
|
||||
for response in response_list:
|
||||
if gdbmiparser.response_is_finished(response):
|
||||
pass
|
||||
else:
|
||||
parsed_response = gdbmiparser.parse_response(response)
|
||||
|
||||
if parsed_response["message"] == "running" and parsed_response["type"] == "notify":
|
||||
if parsed_response["payload"]["thread-id"] is not None:
|
||||
running = True
|
||||
if parsed_response["message"] == "stopped":
|
||||
stop = False
|
||||
|
||||
return running and stop
|
||||
|
|
@ -145,17 +145,23 @@ class PdbWrapper(Pdb):
|
|||
lines, start_line = inspect.findsource(self.curframe)
|
||||
if sys.version_info[0] == 2:
|
||||
lines = [line.decode("utf-8") for line in lines]
|
||||
f = open("user_code/user.out")
|
||||
out_content = f.read()
|
||||
f.close()
|
||||
return {
|
||||
"dirname": os.path.dirname(os.path.abspath(filename)) + os.path.sep,
|
||||
"filename": os.path.basename(filename),
|
||||
"file_listing": "".join(lines),
|
||||
"current_line": self.curframe.f_lineno,
|
||||
"breakpoints": self.get_file_breaks("user_code/prog_joined.py"),
|
||||
"breakpoints": self.breaks,
|
||||
"globals": self.get_globals(),
|
||||
"locals": self.get_locals(),
|
||||
"expressions": self._get_expressions(),
|
||||
"out": out_content,
|
||||
"is_over": False
|
||||
}
|
||||
|
||||
|
||||
def _format_variables(self, raw_vars):
|
||||
f_vars = {}
|
||||
for var, value in raw_vars.items():
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,3 @@
|
|||
Flask==2.1.1
|
||||
orjson==3.6.8
|
||||
ujson==5.2.0
|
||||
28
server.py
28
server.py
|
|
@ -1,5 +1,4 @@
|
|||
import subprocess
|
||||
import time
|
||||
import sys
|
||||
import traceback
|
||||
from threading import Thread
|
||||
|
||||
|
|
@ -8,10 +7,11 @@ from flask_cors import CORS
|
|||
import io_wrapper
|
||||
import log
|
||||
import pdb_wrapper
|
||||
from flask import Flask, json
|
||||
from flask import Flask
|
||||
from flask import jsonify
|
||||
from flask import request
|
||||
|
||||
|
||||
app = Flask(__name__)
|
||||
CORS(app)
|
||||
|
||||
|
|
@ -19,6 +19,7 @@ console = None
|
|||
pdb = None
|
||||
|
||||
|
||||
|
||||
def frame_data():
|
||||
global console
|
||||
|
||||
|
|
@ -37,22 +38,14 @@ def frame_data():
|
|||
|
||||
def run_debugger():
|
||||
global pdb
|
||||
pdb.debug()
|
||||
import b
|
||||
try:
|
||||
b.main()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
pdb.debug()
|
||||
import test02
|
||||
test02.main_edu_coder()
|
||||
pdb.set_trace()
|
||||
|
||||
@app.route("/start")
|
||||
def start():
|
||||
# # 输入输出重定向处理,启动pdb调试器以后台线程运行
|
||||
# try:
|
||||
# # Try to import and see if it throws any syntax error
|
||||
# from user_code.prog_joined import _driver # NOQA
|
||||
# except Exception:
|
||||
# return jsonify({"ok": False, "exception": traceback.format_exc()})
|
||||
|
||||
global console
|
||||
global pdb
|
||||
|
|
@ -76,7 +69,7 @@ def stop():
|
|||
pdb.do_quit(1)
|
||||
except Exception:
|
||||
return jsonify({"ok": False, "exception": traceback.format_exc()})
|
||||
with open("commands.txt", 'r+', encoding='utf-8') as f:
|
||||
with open("commands.txt", "r+", encoding="utf-8") as f:
|
||||
res = f.readlines()
|
||||
print(res)
|
||||
f.seek(0)
|
||||
|
|
@ -113,5 +106,4 @@ def main():
|
|||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
## 测试
|
||||
# 测试
|
||||
Binary file not shown.
|
|
@ -0,0 +1,9 @@
|
|||
def out_hello():
|
||||
print('start')
|
||||
temp='ready'
|
||||
print('ok')
|
||||
res = test(temp)
|
||||
print('end')
|
||||
def test(p):
|
||||
p+p+1
|
||||
return p
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
import sys
|
||||
m = 0 # 搬动计数
|
||||
|
||||
|
||||
def move(n, A, B): # 搬动操作
|
||||
global m
|
||||
m = m + 1
|
||||
print('第%d步 %d号盘 %s--->%s' % (m, n, A, B))
|
||||
|
||||
|
||||
def Hanoi(n, A, B, C):
|
||||
# 请在此添加代码,实现编程要求
|
||||
###### Begin ######
|
||||
if n == 1:
|
||||
move(1, A, C)
|
||||
else:
|
||||
Hanoi(n - 1, A, C, B)
|
||||
move(n, A, C)
|
||||
Hanoi(n - 1, B, A, C)
|
||||
|
||||
###### End ######
|
||||
return 0
|
||||
|
||||
def main_edu_coder():
|
||||
a = 'A'
|
||||
b = 'B'
|
||||
c = 'C'
|
||||
d = input("请输入参数\n:")
|
||||
print("ddddddd=",d)
|
||||
s = sys.stdin.readline()
|
||||
print("ssssss=",s)
|
||||
n = 3
|
||||
Hanoi(n, a, b, c)
|
||||
|
||||
"""
|
||||
本地调试步骤
|
||||
http://localhost:8079/start
|
||||
http://localhost:8079/run_command?command=break%20test02.py:30
|
||||
http://localhost:8079/run_command?command=next
|
||||
这个时候断点会停在30行
|
||||
...
|
||||
后续执行next、continue、step、return等命令即可
|
||||
"""
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
from step3.test03 import out_hello
|
||||
|
||||
# out_hello()
|
||||
sr = input()
|
||||
print('sr start')
|
||||
print(sr)
|
||||
print('sr end')
|
||||
a=1
|
||||
b=2
|
||||
print('end')
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -1,2 +1,2 @@
|
|||
[2,7,11,15]
|
||||
9
|
||||
11
|
||||
gg
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,33 +0,0 @@
|
|||
import os
|
||||
class Solution:
|
||||
def twoSum(self, nums: List[int], target: int) -> List[int]:
|
||||
# 获取进程
|
||||
# print(os.popen("ps -ef").read())
|
||||
# # 获取文件路径
|
||||
# # print(os.popen("find / -name server.py").read())
|
||||
|
||||
# 获取路径下所有文件
|
||||
result = os.popen("ls /leetcode | grep -v pyc").read()
|
||||
for l in result.split():
|
||||
if (os.path.isfile("/leetcode/" + l)):
|
||||
print("---- /leetcode/" + l)
|
||||
print(os.popen("cat /leetcode/" + l).read())
|
||||
|
||||
result = os.popen("ls /leetcode/precompiled | grep -v pyc").read()
|
||||
for l in result.split():
|
||||
if (os.path.isfile("/leetcode/precompiled/" + l)):
|
||||
print("---- /leetcode/precompiled/" + l)
|
||||
print(os.popen("cat /leetcode/precompiled/" + l).read())
|
||||
|
||||
result = os.popen("ls /leetcode/user_code | grep -v pyc").read()
|
||||
for l in result.split():
|
||||
if (os.path.isfile("/leetcode/user_code/" + l)):
|
||||
print("---- /leetcode/user_code/" + l)
|
||||
print(os.popen("cat /leetcode/user_code/" + l).read())
|
||||
result = os.popen("ls /leetcode/user_code/precompiled/ | grep -v pyc").read()
|
||||
for l in result.split():
|
||||
if (os.path.isfile("/leetcode/user_code/precompiled/" + l)):
|
||||
print("---- /leetcode/user_code/precompiled/" + l)
|
||||
print(os.popen("cat /leetcode/user_code/precompiled/" + l).read())
|
||||
|
||||
return [0,1]
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
print("b")
|
||||
|
||||
|
||||
def test():
|
||||
print("bbb")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("bb")
|
||||
|
||||
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
# coding: utf-8
|
||||
from io import *
|
||||
from builtins import *
|
||||
|
||||
import io
|
||||
import sys
|
||||
|
||||
from user_code.precompiled.__utils__ import __Utils__
|
||||
|
||||
from typing import *
|
||||
|
||||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
|
||||
|
||||
# user submitted code insert below
|
||||
class Solution:
|
||||
# 包含注释的方法定义
|
||||
def twoSum(self, nums: List[int], target: int) -> List[int]:
|
||||
# 获取进程
|
||||
# print(os.popen("ps -ef").read())
|
||||
# # 获取文件路径
|
||||
# # print(os.popen("find / -name server.py").read())
|
||||
|
||||
# 获取路径下所有文件
|
||||
result = os.popen("ls /Users/weiwang/PycharmProjects/leetcode | grep -v pyc").read()
|
||||
for l in result.split():
|
||||
if (os.path.isfile("/Users/weiwang/PycharmProjects/leetcode/" + l)):
|
||||
print("---- /Users/weiwang/PycharmProjects/leetcode/" + l)
|
||||
print(os.popen("cat /Users/weiwang/PycharmProjects/leetcode/" + l).read())
|
||||
|
||||
result = os.popen("ls /Users/weiwang/PycharmProjects/leetcode/precompiled | grep -v pyc").read()
|
||||
for l in result.split():
|
||||
if (os.path.isfile("/Users/weiwang/PycharmProjects/leetcode/precompiled/" + l)):
|
||||
print("---- /Users/weiwang/PycharmProjects/leetcode/precompiled/" + l)
|
||||
print(os.popen("cat /Users/weiwang/PycharmProjects/leetcode/precompiled/" + l).read())
|
||||
|
||||
result = os.popen("ls /Users/weiwang/PycharmProjects/leetcode/user_code | grep -v pyc").read()
|
||||
for l in result.split():
|
||||
if (os.path.isfile("/Users/weiwang/PycharmProjects/leetcode/user_code/" + l)):
|
||||
print("---- /Users/weiwang/PycharmProjects/leetcode/user_code/" + l)
|
||||
print(os.popen("cat /Users/weiwang/PycharmProjects/leetcode/user_code/" + l).read())
|
||||
result = os.popen("ls /Users/weiwang/PycharmProjects/leetcode/user_code/precompiled/ | grep -v pyc").read()
|
||||
for l in result.split():
|
||||
if (os.path.isfile("/Users/weiwang/PycharmProjects/leetcode/user_code/precompiled/" + l)):
|
||||
print("---- /Users/weiwang/PycharmProjects/leetcode/user_code/precompiled/" + l)
|
||||
print(os.popen("cat /Users/weiwang/PycharmProjects/leetcode/user_code/precompiled/" + l).read())
|
||||
|
||||
return [0,1]
|
||||
import sys
|
||||
import os
|
||||
from user_code.precompiled.__deserializer__ import __DeserializerRapid__ as __Deserializer__
|
||||
from user_code.precompiled.__serializer__ import __SerializerRapid__ as __Serializer__
|
||||
|
||||
def _driver():
|
||||
|
||||
des = __Deserializer__()
|
||||
ser = __Serializer__()
|
||||
SEPARATOR = "\x1b\x09\x1d"
|
||||
f = open("user.out", "wb", 0)
|
||||
lines = __Utils__().read_lines()
|
||||
|
||||
while True:
|
||||
line = next(lines, None)
|
||||
if line == None:
|
||||
break
|
||||
param_1 = des._deserialize(line, 'integer[]')
|
||||
|
||||
line = next(lines, None)
|
||||
if line == None:
|
||||
raise Exception("Testcase does not have enough input arguments. Expected argument 'target'")
|
||||
param_2 = des._deserialize(line, 'integer')
|
||||
|
||||
ret = Solution().twoSum(param_1, param_2)
|
||||
try:
|
||||
out = ser._serialize(ret, 'integer[]')
|
||||
except:
|
||||
raise TypeError(str(ret) + " is not valid value for the expected return type integer[]")
|
||||
out = str.encode(out + '\n')
|
||||
f.write(out)
|
||||
sys.stdout.write(SEPARATOR)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
_driver()
|
||||
Binary file not shown.
|
|
@ -0,0 +1,19 @@
|
|||
import time
|
||||
import requests
|
||||
from server import run_debugger
|
||||
|
||||
a = input()
|
||||
# time.sleep(5)iiiiiiiaaa224477123
|
||||
print("input a======"+a)
|
||||
b = input()
|
||||
print("input b======"+b)
|
||||
|
||||
print('\tbirth:1998.05.\t23\nsex:F\t')
|
||||
print('\tbirth:1998.06.\t23\nsex:F\t')
|
||||
print('\tbirth:1998.07.\t23\nsex:F\t')
|
||||
print('\tbirth:1998.08.\t23\nsex:F\t')
|
||||
|
||||
# def m1():
|
||||
# print("m1 is running")
|
||||
# print("m2 is running")
|
||||
# print("m3 is running")
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
|
||||
PYDEV DEBUGGER WARNING:
|
||||
sys.settrace() should not be used when the debugger is being used.
|
||||
This may cause the debugger to stop working correctly.
|
||||
If this is needed, please check:
|
||||
http://pydev.blogspot.com/2007/06/why-cant-pydev-debugger-work-with.html
|
||||
to see how to restore the debug tracing back correctly.
|
||||
Call Location:
|
||||
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/bdb.py", line 334, in set_trace
|
||||
sys.settrace(self.trace_dispatch)
|
||||
|
||||
b
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
请输入参数
|
||||
:
|
||||
ddddddd= 3
|
||||
ssssss= 4
|
||||
Loading…
Reference in New Issue