6 """ |
6 """ |
7 Module implementing the debug server. |
7 Module implementing the debug server. |
8 """ |
8 """ |
9 |
9 |
10 import os |
10 import os |
|
11 import shlex |
11 |
12 |
12 from PyQt5.QtCore import pyqtSignal, pyqtSlot, QModelIndex |
13 from PyQt5.QtCore import pyqtSignal, pyqtSlot, QModelIndex |
13 from PyQt5.QtNetwork import ( |
14 from PyQt5.QtNetwork import ( |
14 QTcpServer, QHostAddress, QHostInfo, QNetworkInterface |
15 QTcpServer, QHostAddress, QHostInfo, QNetworkInterface |
15 ) |
16 ) |
20 from .BreakPointModel import BreakPointModel |
21 from .BreakPointModel import BreakPointModel |
21 from .WatchPointModel import WatchPointModel |
22 from .WatchPointModel import WatchPointModel |
22 from . import DebugClientCapabilities |
23 from . import DebugClientCapabilities |
23 |
24 |
24 import Preferences |
25 import Preferences |
25 import Utilities |
|
26 |
26 |
27 |
27 |
28 DebuggerInterfaces = { |
28 DebuggerInterfaces = { |
29 "Python": "DebuggerInterfacePython", |
29 "Python": "DebuggerInterfacePython", |
30 "None": "DebuggerInterfaceNone", |
30 "None": "DebuggerInterfaceNone", |
71 @signal clientDisconnected(str) emitted after a debug client has |
71 @signal clientDisconnected(str) emitted after a debug client has |
72 disconnected (i.e. closed the network socket) |
72 disconnected (i.e. closed the network socket) |
73 @signal clientExit(str, int, str, bool, str) emitted after the client has |
73 @signal clientExit(str, int, str, bool, str) emitted after the client has |
74 exited giving the program name, the exit status, an exit message, an |
74 exited giving the program name, the exit status, an exit message, an |
75 indication to be quiet and the ID of the exited client |
75 indication to be quiet and the ID of the exited client |
|
76 @signal mainClientExit() emitted to indicate that the main client process |
|
77 has exited |
76 @signal lastClientExited() emitted to indicate that the last connected |
78 @signal lastClientExited() emitted to indicate that the last connected |
77 debug client has terminated |
79 debug client has terminated |
78 @signal clientClearBreak(filename, lineno, debuggerId) emitted after the |
80 @signal clientClearBreak(filename, lineno, debuggerId) emitted after the |
79 debug client has decided to clear a temporary breakpoint |
81 debug client has decided to clear a temporary breakpoint |
80 @signal clientBreakConditionError(fn, lineno, debuggerId) emitted after the |
82 @signal clientBreakConditionError(fn, lineno, debuggerId) emitted after the |
143 clientException = pyqtSignal(str, str, list, str, str) |
145 clientException = pyqtSignal(str, str, list, str, str) |
144 clientSyntaxError = pyqtSignal(str, str, int, int, str, str) |
146 clientSyntaxError = pyqtSignal(str, str, int, int, str, str) |
145 clientSignal = pyqtSignal(str, str, int, str, str, str) |
147 clientSignal = pyqtSignal(str, str, int, str, str, str) |
146 clientDisconnected = pyqtSignal(str) |
148 clientDisconnected = pyqtSignal(str) |
147 clientExit = pyqtSignal(str, int, str, bool, str) |
149 clientExit = pyqtSignal(str, int, str, bool, str) |
|
150 mainClientExit = pyqtSignal() |
148 lastClientExited = pyqtSignal() |
151 lastClientExited = pyqtSignal() |
149 clientBreakConditionError = pyqtSignal(str, int, str) |
152 clientBreakConditionError = pyqtSignal(str, int, str) |
150 clientWatchConditionError = pyqtSignal(str, str) |
153 clientWatchConditionError = pyqtSignal(str, str) |
151 clientRawInput = pyqtSignal(str, bool, str) |
154 clientRawInput = pyqtSignal(str, bool, str) |
152 clientBanner = pyqtSignal(str, str, str) |
155 clientBanner = pyqtSignal(str, str, str) |
166 utFinished = pyqtSignal() |
169 utFinished = pyqtSignal() |
167 passiveDebugStarted = pyqtSignal(str, bool) |
170 passiveDebugStarted = pyqtSignal(str, bool) |
168 callTraceInfo = pyqtSignal(bool, str, str, str, str, str, str, str) |
171 callTraceInfo = pyqtSignal(bool, str, str, str, str, str, str, str) |
169 appendStdout = pyqtSignal(str) |
172 appendStdout = pyqtSignal(str) |
170 |
173 |
171 def __init__(self, originalPathString, preventPassiveDebugging=False): |
174 def __init__(self, originalPathString, preventPassiveDebugging=False, |
|
175 project=None): |
172 """ |
176 """ |
173 Constructor |
177 Constructor |
174 |
178 |
175 @param originalPathString original PATH environment variable |
179 @param originalPathString original PATH environment variable |
176 @type str |
180 @type str |
177 @param preventPassiveDebugging flag overriding the PassiveDbgEnabled |
181 @param preventPassiveDebugging flag overriding the PassiveDbgEnabled |
178 setting |
182 setting (defaults to False) |
179 @type bool |
183 @type bool (optional) |
|
184 @param project reference to the project object (defaults to None) |
|
185 @type Project (optional) |
180 """ |
186 """ |
181 super(DebugServer, self).__init__() |
187 super(DebugServer, self).__init__() |
182 |
188 |
183 self.__originalPathString = originalPathString |
189 self.__originalPathString = originalPathString |
184 |
190 |
191 # function reference to create the debugger interface (see |
197 # function reference to create the debugger interface (see |
192 # __createDebuggerInterface() below) and the interface name is |
198 # __createDebuggerInterface() below) and the interface name is |
193 # the value |
199 # the value |
194 |
200 |
195 # create our models |
201 # create our models |
196 self.breakpointModel = BreakPointModel(self) |
202 self.breakpointModel = BreakPointModel(project, self) |
197 self.watchpointModel = WatchPointModel(self) |
203 self.watchpointModel = WatchPointModel(self) |
198 self.watchSpecialCreated = self.tr( |
204 self.watchSpecialCreated = self.tr( |
199 "created", "must be same as in EditWatchpointDialog") |
205 "created", "must be same as in EditWatchpointDialog") |
200 self.watchSpecialChanged = self.tr( |
206 self.watchSpecialChanged = self.tr( |
201 "changed", "must be same as in EditWatchpointDialog") |
207 "changed", "must be same as in EditWatchpointDialog") |
908 Public method to set the environment for a program to debug, run, ... |
914 Public method to set the environment for a program to debug, run, ... |
909 |
915 |
910 @param env environment settings |
916 @param env environment settings |
911 @type str |
917 @type str |
912 """ |
918 """ |
913 envlist = Utilities.parseEnvironmentString(env) |
919 envlist = shlex.split(env) |
914 envdict = {} |
920 envdict = {} |
915 for el in envlist: |
921 for el in envlist: |
916 try: |
922 if '=' in el: |
917 key, value = el.split('=', 1) |
923 key, value = el.split('=', 1) |
918 if value.startswith('"') or value.startswith("'"): |
|
919 value = value[1:-1] |
|
920 envdict[key] = value |
924 envdict[key] = value |
921 except ValueError: |
925 else: |
922 pass |
926 envdict[el] = "" |
923 self.debuggerInterface.remoteEnvironment(envdict) |
927 self.debuggerInterface.remoteEnvironment(envdict) |
924 |
928 |
925 def remoteLoad(self, venvName, fn, argv, wd, env, autoClearShell=True, |
929 def remoteLoad(self, venvName, fn, argv, wd, env, autoClearShell=True, |
926 tracePython=False, autoContinue=True, forProject=False, |
930 tracePython=False, autoContinue=True, forProject=False, |
927 runInConsole=False, clientType="", enableCallTrace=False, |
931 runInConsole=False, clientType="", enableCallTrace=False, |
1846 @type str |
1850 @type str |
1847 @param debuggerId ID of the debugger backend |
1851 @param debuggerId ID of the debugger backend |
1848 @type str |
1852 @type str |
1849 """ |
1853 """ |
1850 self.clientExit.emit(program, int(status), message, False, debuggerId) |
1854 self.clientExit.emit(program, int(status), message, False, debuggerId) |
|
1855 |
|
1856 def signalMainClientExit(self): |
|
1857 """ |
|
1858 Public method to process the main client exiting. |
|
1859 """ |
|
1860 self.mainClientExit.emit() |
1851 |
1861 |
1852 def signalLastClientExited(self): |
1862 def signalLastClientExited(self): |
1853 """ |
1863 """ |
1854 Public method to process the last client exit event. |
1864 Public method to process the last client exit event. |
1855 """ |
1865 """ |