diff -r ab8f95bc7d2d -r eb65864ca038 eric6/DebugClients/Python/DebugClientBase.py --- a/eric6/DebugClients/Python/DebugClientBase.py Mon Dec 07 19:53:15 2020 +0100 +++ b/eric6/DebugClients/Python/DebugClientBase.py Thu Dec 10 20:16:21 2020 +0100 @@ -31,7 +31,7 @@ from FlexCompleter import Completer from DebugUtilities import prepareJsonCommand from BreakpointWatch import Breakpoint, Watch -##from MultiProcessDebugExtension import patchNewProcessFunctions +from MultiProcessDebugExtension import patchNewProcessFunctions from DebugUtilities import getargvalues, formatargvalues @@ -68,25 +68,6 @@ ############################################################################### -def DebugClientFork(): - """ - Replacement for the standard os.fork(). - - @return result of the fork() call - """ - if DebugClientInstance is None: - return DebugClientOrigFork() - - return DebugClientInstance.fork() - -# use our own fork(). -if 'fork' in dir(os): - DebugClientOrigFork = os.fork - os.fork = DebugClientFork - -############################################################################### - - def DebugClientClose(fd): """ Replacement for the standard os.close(fd). @@ -182,9 +163,6 @@ self.debugging = False self.multiprocessSupport = False self.noDebugList = [] - - self.fork_auto = False - self.fork_child = False self.readstream = None self.writestream = None @@ -284,13 +262,29 @@ """ Private method to compile source code read from a file. - @param filename name of the source file (string) - @param mode kind of code to be generated (string, exec or eval) + @param filename name of the source file + @type str + @param mode kind of code to be generated (exec or eval) + @type str @return compiled code object (None in case of errors) """ with codecs.open(filename, encoding=self.__coding) as fp: statement = fp.read() + return self.__compileCommand(statement, filename=filename, mode=mode) + + def __compileCommand(self, statement, filename="<string>", mode="exec"): + """ + Private method to compile source code. + + @param statement source code string to be compiled + @type str + @param filename name of the source file + @type str + @param mode kind of code to be generated (exec or eval) + @type str + @return compiled code object (None in case of errors) + """ try: code = compile(statement + '\n', filename, mode) except SyntaxError: @@ -432,9 +426,6 @@ self.debugging = True self.multiprocessSupport = params["multiprocess"] - self.fork_auto = params["autofork"] - self.fork_child = params["forkChild"] - self.threads.clear() self.attachThread(mainThread=True) @@ -473,9 +464,6 @@ self.running = sys.argv[0] self.botframe = None - self.fork_auto = params["autofork"] - self.fork_child = params["forkChild"] - self.threads.clear() self.attachThread(mainThread=True) @@ -932,11 +920,6 @@ elif method == "RequestUTStop": self.testResult.stop() - - elif method == "ResponseForkTo": - # this results from a separate event loop - self.fork_child = (params["target"] == 'child') - self.eventExit = True def __assembleTestCasesList(self, suite, start): """ @@ -2054,7 +2037,7 @@ def startProgInDebugger(self, progargs, wd='', host=None, port=None, exceptions=True, tracePython=False, redirect=True, passive=True, - multiprocessSupport=False): + multiprocessSupport=False, codeStr=""): """ Public method used to start the remote debugger. @@ -2074,6 +2057,8 @@ @param multiprocessSupport flag indicating to enable multiprocess debugging support @type bool + @param codeStr string containing Python code to execute + @type str @return exit code of the debugged program @rtype int """ @@ -2088,15 +2073,19 @@ self._fncache = {} self.dircache = [] - sys.argv = progargs[:] - sys.argv[0] = os.path.abspath(sys.argv[0]) - sys.path = self.__getSysPath(os.path.dirname(sys.argv[0])) - if wd == '': - os.chdir(sys.path[1]) + if codeStr: + self.running = "<string>" + sys.argv = ["<string>"] + progargs[:] else: - os.chdir(wd) - self.running = sys.argv[0] - self.__setCoding(self.running) + sys.argv = progargs[:] + sys.argv[0] = os.path.abspath(sys.argv[0]) + sys.path = self.__getSysPath(os.path.dirname(sys.argv[0])) + if wd == '': + os.chdir(sys.path[1]) + else: + os.chdir(wd) + self.running = sys.argv[0] + self.__setCoding(self.running) self.debugging = True self.multiprocessSupport = multiprocessSupport @@ -2116,7 +2105,10 @@ # This will eventually enter a local event loop. self.debugMod.__dict__['__file__'] = self.running sys.modules['__main__'] = self.debugMod - code = self.__compileFileSource(self.running) + if codeStr: + code = self.__compileCommand(codeStr) + else: + code = self.__compileFileSource(self.running) if code: res = self.mainThread.run(code, self.debugMod.__dict__, debug=True) else: @@ -2179,6 +2171,7 @@ redirect = True passive = True multiprocess = False + hasCode = False while args[0]: if args[0] == '-h': host = args[1] @@ -2204,20 +2197,15 @@ elif args[0] == '--no-encoding': self.noencoding = True del args[0] - elif args[0] == '--fork-child': - self.fork_auto = True - self.fork_child = True - del args[0] - elif args[0] == '--fork-parent': - self.fork_auto = True - self.fork_child = False - del args[0] elif args[0] == '--no-passive': passive = False del args[0] elif args[0] == '--multiprocess': multiprocess = True del args[0] + elif args[0] == '--code': + hasCode = True + del args[0] elif args[0] == '--': del args[0] break @@ -2234,15 +2222,20 @@ # TODO: check which ones are really needed self.startOptions = ( wd, host, port, exceptions, tracePython, redirect, - self.noencoding, self.fork_auto, self.fork_child, + self.noencoding, ) if not self.noencoding: self.__coding = self.defaultCoding -## patchNewProcessFunctions(multiprocess, self) + patchNewProcessFunctions(multiprocess, self) + if hasCode: + codeStr = args.pop(0) + else: + codeStr="" res = self.startProgInDebugger( args, wd, host, port, exceptions=exceptions, tracePython=tracePython, redirect=redirect, - passive=passive, multiprocessSupport=multiprocess + passive=passive, multiprocessSupport=multiprocess, + codeStr=codeStr ) sys.exit(res) else: @@ -2291,49 +2284,17 @@ # TODO: check which ones are really needed self.startOptions = ( '', remoteAddress, port, True, False, redirect, - self.noencoding, self.fork_auto, self.fork_child, + self.noencoding, ) if not self.noencoding: self.__coding = self.defaultCoding + patchNewProcessFunctions(self.multiprocessSupport, self) self.connectDebugger(port, remoteAddress, redirect) -## patchNewProcessFunctions(self.multiprocessSupport, self) self.__interact() else: print("No network port given. Aborting...") # __IGNORE_WARNING_M801__ - def fork(self): - """ - Public method implementing a fork routine deciding which branch - to follow. - - @return process ID (integer) - """ -## if not self.fork_auto: -## self.sendJsonCommand("RequestForkTo", {}) -## self.eventLoop(True) - pid = DebugClientOrigFork() - if pid == 0: - # child -## if not self.fork_child: - sys.settrace(None) - sys.setprofile(None) - self.sessionClose(False) -## (wd, host, port, exceptions, tracePython, redirect, -## noencoding, fork_auto, fork_child) = self.startOptions -## self.startDebugger(sys.argv[0], host, port, -## exceptions=exceptions, -## tracePython=tracePython, -## redirect=redirect, -## passive=False) - else: - # parent - if self.fork_child: - sys.settrace(None) - sys.setprofile(None) - self.sessionClose(False) - return pid - def close(self, fd): """ Public method implementing a close method as a replacement for