7 Module implementing the debugger UI. |
7 Module implementing the debugger UI. |
8 """ |
8 """ |
9 |
9 |
10 import os |
10 import os |
11 |
11 |
12 from PyQt5.QtCore import pyqtSignal, QObject, Qt |
12 from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, Qt |
13 from PyQt5.QtGui import QKeySequence |
13 from PyQt5.QtGui import QKeySequence |
14 from PyQt5.QtWidgets import QMenu, QToolBar, QApplication, QDialog |
14 from PyQt5.QtWidgets import QMenu, QToolBar, QApplication, QDialog |
15 |
15 |
|
16 from E5Gui.E5Action import E5Action, createActionGroup |
|
17 from E5Gui import E5MessageBox |
|
18 |
16 from UI.Info import Program |
19 from UI.Info import Program |
|
20 from UI.NotificationWidget import NotificationTypes |
17 |
21 |
18 from .DebugClientCapabilities import ( |
22 from .DebugClientCapabilities import ( |
19 HasDebugger, HasInterpreter, HasProfiler, HasCoverage |
23 HasDebugger, HasInterpreter, HasProfiler, HasCoverage |
20 ) |
24 ) |
|
25 |
21 import Preferences |
26 import Preferences |
22 import Utilities |
27 import Utilities |
23 import UI.PixmapCache |
28 import UI.PixmapCache |
24 import UI.Config |
29 import UI.Config |
25 |
30 |
26 from E5Gui.E5Action import E5Action, createActionGroup |
|
27 from E5Gui import E5MessageBox |
|
28 |
|
29 from eric6config import getConfig |
31 from eric6config import getConfig |
30 |
32 |
31 |
33 |
32 class DebugUI(QObject): |
34 class DebugUI(QObject): |
33 """ |
35 """ |
34 Class implementing the debugger part of the UI. |
36 Class implementing the debugger part of the UI. |
35 |
37 |
36 @signal clientStack(stack) emitted at breaking after a reported exception |
38 @signal clientStack(stack, debuggerId) emitted at breaking after a reported |
|
39 exception |
37 @signal compileForms() emitted if changed project forms should be compiled |
40 @signal compileForms() emitted if changed project forms should be compiled |
38 @signal compileResources() emitted if changed project resources should be |
41 @signal compileResources() emitted if changed project resources should be |
39 compiled |
42 compiled |
40 @signal executeMake() emitted if a project specific make run should be |
43 @signal executeMake() emitted if a project specific make run should be |
41 performed |
44 performed |
42 @signal debuggingStarted(filename) emitted when a debugging session was |
45 @signal debuggingStarted(filename) emitted when a debugging session was |
43 started |
46 started |
44 @signal resetUI() emitted to reset the UI |
47 @signal resetUI(full) emitted to reset the UI partially or fully |
45 @signal exceptionInterrupt() emitted after the execution was interrupted |
48 @signal exceptionInterrupt() emitted after the execution was interrupted |
46 by an exception and acknowledged by the user |
49 by an exception and acknowledged by the user |
47 @signal appendStdout(msg) emitted when the client program has terminated |
50 @signal appendStdout(msg) emitted when the client program has terminated |
48 and the display of the termination dialog is suppressed |
51 and the display of the termination dialog is suppressed |
49 """ |
52 """ |
50 clientStack = pyqtSignal(list) |
53 clientStack = pyqtSignal(list, str) |
51 resetUI = pyqtSignal() |
54 resetUI = pyqtSignal(bool) |
52 exceptionInterrupt = pyqtSignal() |
55 exceptionInterrupt = pyqtSignal() |
53 compileForms = pyqtSignal() |
56 compileForms = pyqtSignal() |
54 compileResources = pyqtSignal() |
57 compileResources = pyqtSignal() |
55 executeMake = pyqtSignal() |
58 executeMake = pyqtSignal() |
56 debuggingStarted = pyqtSignal(str) |
59 debuggingStarted = pyqtSignal(str) |
99 Preferences.Prefs.settings.value('DebugInfo/AutoClearShell', True)) |
102 Preferences.Prefs.settings.value('DebugInfo/AutoClearShell', True)) |
100 self.tracePython = Preferences.toBool( |
103 self.tracePython = Preferences.toBool( |
101 Preferences.Prefs.settings.value('DebugInfo/TracePython', False)) |
104 Preferences.Prefs.settings.value('DebugInfo/TracePython', False)) |
102 self.autoContinue = Preferences.toBool( |
105 self.autoContinue = Preferences.toBool( |
103 Preferences.Prefs.settings.value('DebugInfo/AutoContinue', True)) |
106 Preferences.Prefs.settings.value('DebugInfo/AutoContinue', True)) |
104 self.forkAutomatically = Preferences.toBool( |
107 self.enableMultiprocess = Preferences.toBool( |
105 Preferences.Prefs.settings.value( |
108 Preferences.Prefs.settings.value( |
106 'DebugInfo/ForkAutomatically', False)) |
109 'DebugInfo/EnableMultiprocess', False)) |
107 self.forkIntoChild = Preferences.toBool( |
110 self.multiprocessNoDebugHistory = Preferences.toList( |
108 Preferences.Prefs.settings.value('DebugInfo/ForkIntoChild', False)) |
111 Preferences.Prefs.settings.value( |
|
112 'DebugInfo/MultiprocessNoDebugHistory')) |
109 |
113 |
110 self.lastDebuggedFile = None |
114 self.lastDebuggedFile = None |
111 self.lastStartAction = 0 # 0=None, 1=Script, 2=Project |
115 self.lastStartAction = 0 # 0=None, 1=Script, 2=Project |
112 self.clientType = "" |
116 self.clientType = "" |
113 self.lastAction = -1 |
117 self.lastAction = -1 |
114 self.debugActions = [ |
118 self.debugActions = [ |
115 self.__continue, self.__step, self.__stepOver, self.__stepOut, |
119 self.__continue, self.__step, self.__stepOver, self.__stepOut, |
116 self.__stepQuit, self.__runToCursor, self.__moveInstructionPointer |
120 self.__stepQuit, self.__runToCursor, self.__runUntil, |
|
121 self.__moveInstructionPointer |
117 ] |
122 ] |
118 self.localsVarFilter, self.globalsVarFilter = ( |
123 self.__localsVarFilterList, self.__globalsVarFilterList = ( |
119 Preferences.getVarFilters()) |
124 Preferences.getVarFilters()) |
120 self.debugViewer.setVariablesFilter( |
125 self.debugViewer.setVariablesFilter( |
121 self.globalsVarFilter, self.localsVarFilter) |
126 self.__globalsVarFilterList, self.__localsVarFilterList) |
|
127 |
|
128 self.__clientDebuggerIds = set() |
122 |
129 |
123 # Connect the signals emitted by the debug-server |
130 # Connect the signals emitted by the debug-server |
124 debugServer.clientGone.connect(self.__clientGone) |
131 debugServer.clientGone.connect(self.__clientGone) |
125 debugServer.clientLine.connect(self.__clientLine) |
132 debugServer.clientLine.connect(self.__clientLine) |
|
133 debugServer.clientDisconnected.connect(self.__clientDisconnected) |
126 debugServer.clientExit.connect(self.__clientExit) |
134 debugServer.clientExit.connect(self.__clientExit) |
|
135 debugServer.lastClientExited.connect(self.__lastClientExited) |
127 debugServer.clientSyntaxError.connect(self.__clientSyntaxError) |
136 debugServer.clientSyntaxError.connect(self.__clientSyntaxError) |
128 debugServer.clientException.connect(self.__clientException) |
137 debugServer.clientException.connect(self.__clientException) |
129 debugServer.clientSignal.connect(self.__clientSignal) |
138 debugServer.clientSignal.connect(self.__clientSignal) |
130 debugServer.clientVariables.connect(self.__clientVariables) |
139 debugServer.clientVariables.connect(self.__clientVariables) |
131 debugServer.clientVariable.connect(self.__clientVariable) |
140 debugServer.clientVariable.connect(self.__clientVariable) |
150 project.newProject.connect(self.__projectOpened) |
158 project.newProject.connect(self.__projectOpened) |
151 project.projectClosed.connect(self.__projectClosed) |
159 project.projectClosed.connect(self.__projectClosed) |
152 |
160 |
153 # Set a flag for the passive debug mode |
161 # Set a flag for the passive debug mode |
154 self.passive = Preferences.getDebugger("PassiveDbgEnabled") |
162 self.passive = Preferences.getDebugger("PassiveDbgEnabled") |
155 |
163 |
|
164 def showNotification(self, notification, |
|
165 kind=NotificationTypes.Information, timeout=None): |
|
166 """ |
|
167 Public method to show some notification message. |
|
168 |
|
169 @param notification message to be shown |
|
170 @type str |
|
171 @param kind kind of notification to be shown |
|
172 @type NotificationTypes |
|
173 @param timeout timeout for the notification (None = use configured |
|
174 default, 0 = indefinitely) |
|
175 @type int |
|
176 """ |
|
177 self.ui.showNotification( |
|
178 UI.PixmapCache.getPixmap("debug48"), |
|
179 self.tr("Notification"), notification, kind=kind, timeout=timeout) |
|
180 |
156 def variablesFilter(self, scope): |
181 def variablesFilter(self, scope): |
157 """ |
182 """ |
158 Public method to get the variables filter for a scope. |
183 Public method to get the variables filter for a scope. |
159 |
184 |
160 @param scope flag indicating global (True) or local (False) scope |
185 @param scope flag indicating global (True) or local (False) scope |
161 @return filters list (list of integers) |
186 @return filters list |
|
187 @rtype list of str |
162 """ |
188 """ |
163 if scope: |
189 if scope: |
164 return self.globalsVarFilter[:] |
190 return self.__globalsVarFilterList[:] |
165 else: |
191 else: |
166 return self.localsVarFilter[:] |
192 return self.__localsVarFilterList[:] |
167 |
193 |
168 def initActions(self): |
194 def initActions(self): |
169 """ |
195 """ |
170 Public method defining the user interface actions. |
196 Public method defining the user interface actions. |
171 """ |
197 """ |
356 """<b>Continue To Cursor</b>""" |
382 """<b>Continue To Cursor</b>""" |
357 """<p>Continue running the program from the current line to the""" |
383 """<p>Continue running the program from the current line to the""" |
358 """ current cursor position.</p>""" |
384 """ current cursor position.</p>""" |
359 )) |
385 )) |
360 act.triggered.connect(self.__runToCursor) |
386 act.triggered.connect(self.__runToCursor) |
|
387 self.actions.append(act) |
|
388 |
|
389 act = E5Action( |
|
390 self.tr('Continue Until'), |
|
391 UI.PixmapCache.getIcon("continueUntil"), |
|
392 self.tr('Continue &Until'), Qt.CTRL + Qt.Key_F6, 0, |
|
393 self.debugActGrp, 'dbg_continue_until') |
|
394 act.setStatusTip(self.tr( |
|
395 """Continue running the program from the current line to the""" |
|
396 """ current cursor position or until leaving the current frame""")) |
|
397 act.setWhatsThis(self.tr( |
|
398 """<b>Continue Until</b>""" |
|
399 """<p>Continue running the program from the current line to the""" |
|
400 """ cursor position greater than the current line or until""" |
|
401 """ leaving the current frame.</p>""" |
|
402 )) |
|
403 act.triggered.connect(self.__runUntil) |
361 self.actions.append(act) |
404 self.actions.append(act) |
362 |
405 |
363 act = E5Action( |
406 act = E5Action( |
364 self.tr('Move Instruction Pointer to Cursor'), |
407 self.tr('Move Instruction Pointer to Cursor'), |
365 UI.PixmapCache.getIcon("moveInstructionPointer"), |
408 UI.PixmapCache.getIcon("moveInstructionPointer"), |
988 ): |
1041 ): |
989 self.restartAct.setEnabled(True) |
1042 self.restartAct.setEnabled(True) |
990 else: |
1043 else: |
991 self.restartAct.setEnabled(False) |
1044 self.restartAct.setEnabled(False) |
992 self.stopAct.setEnabled(False) |
1045 self.stopAct.setEnabled(False) |
993 self.resetUI.emit() |
1046 |
994 |
1047 self.resetUI.emit(fullReset) |
995 def __clientLine(self, fn, line, forStack): |
1048 |
|
1049 def __clientDebuggerId(self, debuggerId): |
|
1050 """ |
|
1051 Private slot to track the list of connected debuggers. |
|
1052 |
|
1053 @param debuggerId ID of the debugger backend |
|
1054 @type str |
|
1055 """ |
|
1056 self.__clientDebuggerIds.add(debuggerId) |
|
1057 |
|
1058 def __clientLine(self, fn, line, debuggerId, threadName, forStack): |
996 """ |
1059 """ |
997 Private method to handle a change to the current line. |
1060 Private method to handle a change to the current line. |
998 |
1061 |
999 @param fn filename (string) |
1062 @param fn filename |
1000 @param line linenumber (int) |
1063 @type str |
1001 @param forStack flag indicating this is for a stack dump (boolean) |
1064 @param line linenumber |
|
1065 @type int |
|
1066 @param debuggerId ID of the debugger backend |
|
1067 @type str |
|
1068 @param threadName name of the thread signaling the event |
|
1069 @type str |
|
1070 @param forStack flag indicating this is for a stack dump |
|
1071 @type bool |
1002 """ |
1072 """ |
1003 self.ui.raise_() |
1073 self.ui.raise_() |
1004 self.ui.activateWindow() |
1074 self.ui.activateWindow() |
1005 if self.ui.getViewProfile() != "debug": |
1075 if self.ui.getViewProfile() != "debug": |
1006 self.ui.setDebugProfile() |
1076 self.ui.setDebugProfile() |
1007 self.viewmanager.setFileLine(fn, line) |
1077 self.viewmanager.setFileLine(fn, line) |
1008 if not forStack: |
1078 if not forStack: |
1009 self.__getThreadList() |
1079 self.__getThreadList(debuggerId) |
1010 self.__getClientVariables() |
1080 self.__getClientVariables(debuggerId) |
1011 |
1081 |
1012 self.debugActGrp.setEnabled(True) |
1082 self.debugActGrp.setEnabled(True) |
1013 |
1083 |
1014 def __clientExit(self, status, message, quiet): |
1084 @pyqtSlot(str) |
1015 """ |
1085 def __clientDisconnected(self, debuggerId): |
1016 Private method to handle the debugged program terminating. |
1086 """ |
1017 |
1087 Private slot to handle a debug client disconnecting its control |
|
1088 socket. |
|
1089 |
|
1090 @param debuggerId ID of the debugger backend |
|
1091 @type str |
|
1092 """ |
|
1093 self.__clientDebuggerIds.discard(debuggerId) |
|
1094 |
|
1095 if len(self.__clientDebuggerIds) == 0: |
|
1096 self.viewmanager.exit() |
|
1097 self.__resetUI(fullReset=False) |
|
1098 |
|
1099 @pyqtSlot(str, int, str, bool, str) |
|
1100 def __clientExit(self, program, status, message, quiet, debuggerId): |
|
1101 """ |
|
1102 Private slot to handle the debugged program terminating. |
|
1103 |
|
1104 @param program name of the exited program |
|
1105 @type str |
1018 @param status exit code of the debugged program |
1106 @param status exit code of the debugged program |
1019 @type int |
1107 @type int |
1020 @param message exit message of the debugged program |
1108 @param message exit message of the debugged program |
1021 @type str |
1109 @type str |
1022 @param quiet flag indicating to suppress exit info display |
1110 @param quiet flag indicating to suppress exit info display |
1023 @type bool |
1111 @type bool |
|
1112 @param debuggerId ID of the debugger backend |
|
1113 @type str |
|
1114 """ |
|
1115 self.__clientDisconnected(debuggerId) |
|
1116 |
|
1117 if not quiet: |
|
1118 if not program: |
|
1119 program = self.ui.currentProg |
|
1120 |
|
1121 if message: |
|
1122 info = self.tr("Message: {0}").format( |
|
1123 Utilities.html_uencode(message)) |
|
1124 else: |
|
1125 info = "" |
|
1126 if program is None: |
|
1127 msg = self.tr( |
|
1128 '<p>The program has terminated with an exit status of' |
|
1129 ' {0}.</p><p>{1}</p>').format(status, info) |
|
1130 else: |
|
1131 msg = self.tr( |
|
1132 '<p><b>{0}</b> has terminated with an exit status of' |
|
1133 ' {1}.</p><p>{2}</p>').format( |
|
1134 os.path.basename(program), status, info) |
|
1135 if status != 0: |
|
1136 timeout = 0 |
|
1137 kind = NotificationTypes.Warning |
|
1138 else: |
|
1139 timeout = None |
|
1140 kind = NotificationTypes.Information |
|
1141 self.ui.showNotification( |
|
1142 UI.PixmapCache.getPixmap("debug48"), |
|
1143 self.tr("Program terminated"), msg, kind=kind, |
|
1144 timeout=timeout) |
|
1145 |
|
1146 def __lastClientExited(self): |
|
1147 """ |
|
1148 Private slot handling the exit of the last client. |
1024 """ |
1149 """ |
1025 self.viewmanager.exit() |
1150 self.viewmanager.exit() |
1026 |
|
1027 self.__resetUI() |
1151 self.__resetUI() |
1028 |
1152 |
1029 if not quiet: |
|
1030 if ( |
|
1031 not Preferences.getDebugger("SuppressClientExit") or |
|
1032 status != 0 |
|
1033 ): |
|
1034 if message: |
|
1035 info = self.tr("<p>Message: {0}</p>").format( |
|
1036 Utilities.html_uencode(message)) |
|
1037 else: |
|
1038 info = "" |
|
1039 if self.ui.currentProg is None: |
|
1040 E5MessageBox.information( |
|
1041 self.ui, Program, |
|
1042 self.tr('<p>The program has terminated with an exit' |
|
1043 ' status of {0}.</p>{1}').format(status, info)) |
|
1044 else: |
|
1045 E5MessageBox.information( |
|
1046 self.ui, Program, |
|
1047 self.tr('<p><b>{0}</b> has terminated with an exit' |
|
1048 ' status of {1}.</p>{2}') |
|
1049 .format(os.path.abspath(self.ui.currentProg), |
|
1050 status, info)) |
|
1051 else: |
|
1052 if message: |
|
1053 info = self.tr("Message: {0}").format( |
|
1054 Utilities.html_uencode(message)) |
|
1055 else: |
|
1056 info = "" |
|
1057 if self.ui.notificationsEnabled(): |
|
1058 if self.ui.currentProg is None: |
|
1059 msg = self.tr( |
|
1060 'The program has terminated with an exit status of' |
|
1061 ' {0}.\n{1}').format(status, info) |
|
1062 else: |
|
1063 msg = self.tr( |
|
1064 '"{0}" has terminated with an exit status of' |
|
1065 ' {1}.\n{2}').format( |
|
1066 os.path.basename(self.ui.currentProg), status, |
|
1067 info) |
|
1068 self.ui.showNotification( |
|
1069 UI.PixmapCache.getPixmap("debug48"), |
|
1070 self.tr("Program terminated"), msg) |
|
1071 else: |
|
1072 if self.ui.currentProg is None: |
|
1073 self.appendStdout.emit(self.tr( |
|
1074 'The program has terminated with an exit status' |
|
1075 ' of {0}.\n{1}\n').format(status, info)) |
|
1076 else: |
|
1077 self.appendStdout.emit(self.tr( |
|
1078 '"{0}" has terminated with an exit status of' |
|
1079 ' {1}.\n{2}\n').format( |
|
1080 os.path.abspath(self.ui.currentProg), status, |
|
1081 info)) |
|
1082 |
|
1083 def __clientSyntaxError(self, message, filename, lineNo, characterNo): |
1153 def __clientSyntaxError(self, message, filename, lineNo, characterNo): |
1084 """ |
1154 """ |
1085 Private method to handle a syntax error in the debugged program. |
1155 Private method to handle a syntax error in the debugged program. |
1086 |
1156 |
1087 @param message message of the syntax error (string) |
1157 @param message message of the syntax error (string) |
1120 self.tr('<p>The file <b>{0}</b> contains the syntax error' |
1190 self.tr('<p>The file <b>{0}</b> contains the syntax error' |
1121 ' <b>{1}</b> at line <b>{2}</b>, character <b>{3}</b>.' |
1191 ' <b>{1}</b> at line <b>{2}</b>, character <b>{3}</b>.' |
1122 '</p>') |
1192 '</p>') |
1123 .format(filename, message, lineNo, characterNo)) |
1193 .format(filename, message, lineNo, characterNo)) |
1124 |
1194 |
1125 def __clientException(self, exceptionType, exceptionMessage, stackTrace): |
1195 def __clientException(self, exceptionType, exceptionMessage, stackTrace, |
|
1196 debuggerId): |
1126 """ |
1197 """ |
1127 Private method to handle an exception of the debugged program. |
1198 Private method to handle an exception of the debugged program. |
1128 |
1199 |
1129 @param exceptionType type of exception raised (string) |
1200 @param exceptionType type of exception raised |
1130 @param exceptionMessage message given by the exception (string) |
1201 @type str |
1131 @param stackTrace list of stack entries (list of string) |
1202 @param exceptionMessage message given by the exception |
|
1203 @type (str |
|
1204 @param stackTrace list of stack entries |
|
1205 @type list of str |
|
1206 @param debuggerId ID of the debugger backend |
|
1207 @type str |
1132 """ |
1208 """ |
1133 self.ui.raise_() |
1209 self.ui.raise_() |
1134 QApplication.processEvents() |
1210 QApplication.processEvents() |
1135 if not exceptionType: |
1211 if not exceptionType: |
1136 E5MessageBox.critical( |
1212 E5MessageBox.critical( |
1210 self.debugServer.setDebugging(True) |
1286 self.debugServer.setDebugging(True) |
1211 self.exceptionInterrupt.emit() |
1287 self.exceptionInterrupt.emit() |
1212 stack = [] |
1288 stack = [] |
1213 for fn, ln, func, args in stackTrace: |
1289 for fn, ln, func, args in stackTrace: |
1214 stack.append((fn, ln, func, args)) |
1290 stack.append((fn, ln, func, args)) |
1215 self.clientStack.emit(stack) |
1291 self.clientStack.emit(stack, debuggerId) |
1216 self.__getClientVariables() |
1292 self.__getClientVariables(debuggerId) |
1217 self.__getClientDisassembly() |
1293 self.__getClientDisassembly(debuggerId) |
1218 self.ui.setDebugProfile() |
1294 self.ui.setDebugProfile() |
1219 self.debugActGrp.setEnabled(True) |
1295 self.debugActGrp.setEnabled(True) |
1220 return |
1296 return |
1221 elif res == E5MessageBox.Ignore: |
1297 elif res == E5MessageBox.Ignore: |
1222 if exceptionType not in self.excIgnoreList: |
1298 if exceptionType not in self.excIgnoreList: |
1223 self.excIgnoreList.append(exceptionType) |
1299 self.excIgnoreList.append(exceptionType) |
1224 |
1300 |
1225 if self.lastAction != -1: |
1301 if self.lastAction != -1: |
1226 if self.lastAction == 2: |
1302 if self.lastAction == 2: |
1227 self.__specialContinue() |
1303 self.__specialContinue(debuggerId) |
1228 else: |
1304 else: |
1229 self.debugActions[self.lastAction]() |
1305 self.debugActions[self.lastAction](debuggerId) |
1230 else: |
1306 else: |
1231 self.__continue() |
1307 self.__continue(debuggerId) |
1232 |
1308 |
1233 def __clientSignal(self, message, filename, lineNo, funcName, funcArgs): |
1309 def __clientSignal(self, message, filename, lineNo, funcName, funcArgs, |
|
1310 debuggerId): |
1234 """ |
1311 """ |
1235 Private method to handle a signal generated on the client side. |
1312 Private method to handle a signal generated on the client side. |
1236 |
1313 |
1237 @param message message of the syntax error |
1314 @param message message of the syntax error |
1238 @type str |
1315 @type str |
1266 E5MessageBox.information( |
1345 E5MessageBox.information( |
1267 self.ui, Program, |
1346 self.ui, Program, |
1268 self.tr('The program being debugged has terminated' |
1347 self.tr('The program being debugged has terminated' |
1269 ' unexpectedly.')) |
1348 ' unexpectedly.')) |
1270 |
1349 |
1271 def __getThreadList(self): |
1350 def __getThreadList(self, debuggerId): |
1272 """ |
1351 """ |
1273 Private method to get the list of threads from the client. |
1352 Private method to get the list of threads from the client. |
1274 """ |
1353 |
1275 self.debugServer.remoteThreadList() |
1354 @param debuggerId ID of the debugger backend |
1276 |
1355 @type str |
1277 def __clientThreadSet(self): |
1356 """ |
|
1357 self.debugServer.remoteThreadList(debuggerId) |
|
1358 |
|
1359 def __clientThreadSet(self, debuggerId): |
1278 """ |
1360 """ |
1279 Private method to handle a change of the client's current thread. |
1361 Private method to handle a change of the client's current thread. |
1280 """ |
1362 |
1281 self.debugServer.remoteClientVariables(0, self.localsVarFilter) |
1363 @param debuggerId ID of the debugger backend |
1282 |
1364 @type str |
1283 def __getClientVariables(self): |
1365 """ |
|
1366 self.debugServer.remoteClientVariables( |
|
1367 debuggerId, 0, self.__localsVarFilterList) |
|
1368 |
|
1369 def __getClientVariables(self, debuggerId): |
1284 """ |
1370 """ |
1285 Private method to request the global and local variables. |
1371 Private method to request the global and local variables. |
1286 |
1372 |
1287 In the first step, the global variables are requested from the client. |
1373 In the first step, the global variables are requested from the client. |
1288 Once these have been received, the local variables are requested. |
1374 Once these have been received, the local variables are requested. |
1289 This happens in the method '__clientVariables'. |
1375 This happens in the method '__clientVariables'. |
|
1376 |
|
1377 @param debuggerId ID of the debugger backend |
|
1378 @type str |
1290 """ |
1379 """ |
1291 # get globals first |
1380 # get globals first |
1292 self.debugServer.remoteClientVariables(1, self.globalsVarFilter) |
1381 self.debugServer.remoteClientVariables( |
|
1382 debuggerId, 1, self.__globalsVarFilterList) |
1293 # the local variables are requested once we have received the globals |
1383 # the local variables are requested once we have received the globals |
1294 |
1384 |
1295 def __clientVariables(self, scope, variables): |
1385 def __clientVariables(self, scope, variables, debuggerId): |
1296 """ |
1386 """ |
1297 Private method to write the clients variables to the user interface. |
1387 Private method to write the clients variables to the user interface. |
1298 |
1388 |
1299 @param scope scope of the variables (-1 = empty global, 1 = global, |
1389 @param scope scope of the variables (-1 = empty locals, 1 = global, |
1300 0 = local) |
1390 0 = local) |
|
1391 @type int |
1301 @param variables the list of variables from the client |
1392 @param variables the list of variables from the client |
1302 """ |
1393 @type list |
1303 self.ui.activateDebugViewer() |
1394 @param debuggerId ID of the debugger backend |
1304 if scope > 0: |
1395 @type str |
1305 self.debugViewer.showVariables(variables, True) |
1396 """ |
1306 if scope == 1: |
1397 if debuggerId == self.getSelectedDebuggerId(): |
1307 # now get the local variables |
1398 self.ui.activateDebugViewer() |
1308 self.debugServer.remoteClientVariables(0, self.localsVarFilter) |
1399 if scope > 0: |
1309 elif scope == 0: |
1400 self.debugViewer.showVariables(variables, True) |
1310 self.debugViewer.showVariables(variables, False) |
1401 if scope == 1: |
1311 elif scope == -1: |
1402 # now get the local variables |
1312 vlist = [(self.tr('No locals available.'), '', '')] |
1403 self.debugServer.remoteClientVariables( |
1313 self.debugViewer.showVariables(vlist, False) |
1404 self.getSelectedDebuggerId(), |
1314 |
1405 0, self.__localsVarFilterList) |
1315 def __clientVariable(self, scope, variables): |
1406 elif scope == 0: |
|
1407 self.debugViewer.showVariables(variables, False) |
|
1408 elif scope == -1: |
|
1409 vlist = [(self.tr('No locals available.'), '', '')] |
|
1410 self.debugViewer.showVariables(vlist, False) |
|
1411 |
|
1412 def __clientVariable(self, scope, variables, debuggerId): |
1316 """ |
1413 """ |
1317 Private method to write the contents of a clients classvariable to |
1414 Private method to write the contents of a clients classvariable to |
1318 the user interface. |
1415 the user interface. |
1319 |
1416 |
1320 @param scope scope of the variables (-1 = empty global, 1 = global, |
1417 @param scope scope of the variables (-1 = empty locals, 1 = global, |
1321 0 = local) |
1418 0 = local) |
1322 @param variables the list of members of a classvariable from the client |
1419 @type int |
1323 """ |
1420 @param variables the list of variables from the client |
1324 self.ui.activateDebugViewer() |
1421 @type list |
1325 if scope == 1: |
1422 @param debuggerId ID of the debugger backend |
1326 self.debugViewer.showVariable(variables, True) |
1423 @type str |
1327 elif scope == 0: |
1424 """ |
1328 self.debugViewer.showVariable(variables, False) |
1425 if debuggerId == self.getSelectedDebuggerId(): |
|
1426 self.ui.activateDebugViewer() |
|
1427 if scope == 1: |
|
1428 self.debugViewer.showVariable(variables, True) |
|
1429 elif scope == 0: |
|
1430 self.debugViewer.showVariable(variables, False) |
1329 |
1431 |
1330 def __getClientDisassembly(self): |
1432 def __getClientDisassembly(self, debuggerId): |
1331 """ |
1433 """ |
1332 Private method to ask the client for the latest traceback disassembly. |
1434 Private method to ask the client for the latest traceback disassembly. |
1333 """ |
1435 |
1334 self.debugServer.remoteClientDisassembly() |
1436 @param debuggerId ID of the debugger backend |
|
1437 @type str |
|
1438 """ |
|
1439 self.debugServer.remoteClientDisassembly(debuggerId) |
1335 |
1440 |
1336 def __clientBreakConditionError(self, filename, lineno): |
1441 def __clientBreakConditionError(self, filename, lineno, debuggerId): |
1337 """ |
1442 """ |
1338 Private method to handle a condition error of a breakpoint. |
1443 Private method to handle a condition error of a breakpoint. |
1339 |
1444 |
1340 @param filename filename of the breakpoint (string) |
1445 @param filename filename of the breakpoint |
1341 @param lineno linenumber of the breakpoint (integer) |
1446 @type str |
|
1447 @param lineno line umber of the breakpoint |
|
1448 @type int |
|
1449 @param debuggerId ID of the debugger backend |
|
1450 @type str |
1342 """ |
1451 """ |
1343 E5MessageBox.critical( |
1452 E5MessageBox.critical( |
1344 self.ui, |
1453 self.ui, |
1345 self.tr("Breakpoint Condition Error"), |
1454 self.tr("Breakpoint Condition Error"), |
1346 self.tr( |
1455 self.tr( |
1366 if dlg.exec() == QDialog.Accepted: |
1475 if dlg.exec() == QDialog.Accepted: |
1367 cond, temp, enabled, count = dlg.getData() |
1476 cond, temp, enabled, count = dlg.getData() |
1368 model.setBreakPointByIndex(index, fn, line, |
1477 model.setBreakPointByIndex(index, fn, line, |
1369 (cond, temp, enabled, count)) |
1478 (cond, temp, enabled, count)) |
1370 |
1479 |
1371 def __clientWatchConditionError(self, cond): |
1480 def __clientWatchConditionError(self, cond, debuggerId): |
1372 """ |
1481 """ |
1373 Private method to handle a expression error of a watch expression. |
1482 Private method to handle a expression error of a watch expression. |
1374 |
1483 |
1375 Note: This can only happen for normal watch expressions |
1484 Note: This can only happen for normal watch expressions |
1376 |
1485 |
1377 @param cond expression of the watch expression (string) |
1486 @param cond expression of the watch expression |
|
1487 @type str |
|
1488 @param debuggerId ID of the debugger backend |
|
1489 @type str |
1378 """ |
1490 """ |
1379 E5MessageBox.critical( |
1491 E5MessageBox.critical( |
1380 self.ui, |
1492 self.ui, |
1381 self.tr("Watch Expression Error"), |
1493 self.tr("Watch Expression Error"), |
1382 self.tr("""<p>The watch expression <b>{0}</b>""" |
1494 self.tr("""<p>The watch expression <b>{0}</b>""" |
1429 """ |
1541 """ |
1430 Private slot for displaying the variables filter configuration dialog. |
1542 Private slot for displaying the variables filter configuration dialog. |
1431 """ |
1543 """ |
1432 from .VariablesFilterDialog import VariablesFilterDialog |
1544 from .VariablesFilterDialog import VariablesFilterDialog |
1433 dlg = VariablesFilterDialog(self.ui, 'Filter Dialog', True) |
1545 dlg = VariablesFilterDialog(self.ui, 'Filter Dialog', True) |
1434 dlg.setSelection(self.localsVarFilter, self.globalsVarFilter) |
1546 dlg.setSelection(self.__localsVarFilterList, |
|
1547 self.__globalsVarFilterList) |
1435 if dlg.exec() == QDialog.Accepted: |
1548 if dlg.exec() == QDialog.Accepted: |
1436 self.localsVarFilter, self.globalsVarFilter = dlg.getSelection() |
1549 self.__localsVarFilterList, self.__globalsVarFilterList = ( |
|
1550 dlg.getSelection() |
|
1551 ) |
1437 self.debugViewer.setVariablesFilter( |
1552 self.debugViewer.setVariablesFilter( |
1438 self.globalsVarFilter, self.localsVarFilter) |
1553 self.__globalsVarFilterList, self.__localsVarFilterList) |
1439 |
1554 |
1440 def __configureExceptionsFilter(self): |
1555 def __configureExceptionsFilter(self): |
1441 """ |
1556 """ |
1442 Private slot for displaying the exception filter dialog. |
1557 Private slot for displaying the exception filter dialog. |
1443 """ |
1558 """ |
1666 |
1782 |
1667 if dlg.clearHistories(): |
1783 if dlg.clearHistories(): |
1668 self.setArgvHistory("", clearHistories=True) |
1784 self.setArgvHistory("", clearHistories=True) |
1669 self.setWdHistory("", clearHistories=True) |
1785 self.setWdHistory("", clearHistories=True) |
1670 self.setEnvHistory("", clearHistories=True) |
1786 self.setEnvHistory("", clearHistories=True) |
|
1787 self.setMultiprocessNoDebugHistory("", clearHistories=True) |
1671 elif dlg.historiesModified(): |
1788 elif dlg.historiesModified(): |
1672 argvHistory, wdHistory, envHistory = dlg.getHistories() |
1789 argvHistory, wdHistory, envHistory, _ = dlg.getHistories() |
1673 self.setArgvHistory("", history=argvHistory) |
1790 self.setArgvHistory("", history=argvHistory) |
1674 self.setWdHistory("", history=wdHistory) |
1791 self.setWdHistory("", history=wdHistory) |
1675 self.setEnvHistory("", history=envHistory) |
1792 self.setEnvHistory("", history=envHistory) |
1676 |
1793 |
1677 def __profileScript(self): |
1794 def __profileScript(self): |
1801 |
1919 |
1802 if dlg.clearHistories(): |
1920 if dlg.clearHistories(): |
1803 self.setArgvHistory("", clearHistories=True) |
1921 self.setArgvHistory("", clearHistories=True) |
1804 self.setWdHistory("", clearHistories=True) |
1922 self.setWdHistory("", clearHistories=True) |
1805 self.setEnvHistory("", clearHistories=True) |
1923 self.setEnvHistory("", clearHistories=True) |
|
1924 self.setMultiprocessNoDebugHistory("", clearHistories=True) |
1806 elif dlg.historiesModified(): |
1925 elif dlg.historiesModified(): |
1807 argvHistory, wdHistory, envHistory = dlg.getHistories() |
1926 argvHistory, wdHistory, envHistory, _ = dlg.getHistories() |
1808 self.setArgvHistory("", history=argvHistory) |
1927 self.setArgvHistory("", history=argvHistory) |
1809 self.setWdHistory("", history=wdHistory) |
1928 self.setWdHistory("", history=wdHistory) |
1810 self.setEnvHistory("", history=envHistory) |
1929 self.setEnvHistory("", history=envHistory) |
1811 |
1930 |
1812 def __runScript(self): |
1931 def __runScript(self): |
1841 else: |
1960 else: |
1842 cap = self.tr("Run Script") |
1961 cap = self.tr("Run Script") |
1843 dlg = StartDialog( |
1962 dlg = StartDialog( |
1844 cap, self.lastUsedVenvName, self.argvHistory, self.wdHistory, |
1963 cap, self.lastUsedVenvName, self.argvHistory, self.wdHistory, |
1845 self.envHistory, self.exceptions, self.ui, 1, |
1964 self.envHistory, self.exceptions, self.ui, 1, |
1846 autoClearShell=self.autoClearShell, |
1965 autoClearShell=self.autoClearShell) |
1847 autoFork=self.forkAutomatically, |
|
1848 forkChild=self.forkIntoChild) |
|
1849 if dlg.exec() == QDialog.Accepted: |
1966 if dlg.exec() == QDialog.Accepted: |
1850 (lastUsedVenvName, argv, wd, env, exceptions, clearShell, |
1967 (lastUsedVenvName, argv, wd, env, exceptions, clearShell, |
1851 console) = dlg.getData() |
1968 console) = dlg.getData() |
1852 forkAutomatically, forkIntoChild = dlg.getRunData() |
|
1853 |
1969 |
1854 if runProject: |
1970 if runProject: |
1855 fn = self.project.getMainScript(True) |
1971 fn = self.project.getMainScript(True) |
1856 if fn is None: |
1972 if fn is None: |
1857 E5MessageBox.critical( |
1973 E5MessageBox.critical( |
1931 |
2044 |
1932 # Ask the client to open the new program. |
2045 # Ask the client to open the new program. |
1933 self.debugServer.remoteRun( |
2046 self.debugServer.remoteRun( |
1934 lastUsedVenvName, fn, argv, wd, env, |
2047 lastUsedVenvName, fn, argv, wd, env, |
1935 autoClearShell=self.autoClearShell, forProject=runProject, |
2048 autoClearShell=self.autoClearShell, forProject=runProject, |
1936 runInConsole=console, autoFork=forkAutomatically, |
2049 runInConsole=console, clientType=self.clientType) |
1937 forkChild=forkIntoChild, clientType=self.clientType) |
|
1938 |
2050 |
1939 self.stopAct.setEnabled(True) |
2051 self.stopAct.setEnabled(True) |
1940 |
2052 |
1941 if dlg.clearHistories(): |
2053 if dlg.clearHistories(): |
1942 self.setArgvHistory("", clearHistories=True) |
2054 self.setArgvHistory("", clearHistories=True) |
1943 self.setWdHistory("", clearHistories=True) |
2055 self.setWdHistory("", clearHistories=True) |
1944 self.setEnvHistory("", clearHistories=True) |
2056 self.setEnvHistory("", clearHistories=True) |
|
2057 self.setMultiprocessNoDebugHistory("", clearHistories=True) |
1945 elif dlg.historiesModified(): |
2058 elif dlg.historiesModified(): |
1946 argvHistory, wdHistory, envHistory = dlg.getHistories() |
2059 argvHistory, wdHistory, envHistory, _ = dlg.getHistories() |
1947 self.setArgvHistory("", history=argvHistory) |
2060 self.setArgvHistory("", history=argvHistory) |
1948 self.setWdHistory("", history=wdHistory) |
2061 self.setWdHistory("", history=wdHistory) |
1949 self.setEnvHistory("", history=envHistory) |
2062 self.setEnvHistory("", history=envHistory) |
1950 |
2063 |
1951 def __debugScript(self): |
2064 def __debugScript(self): |
1981 cap = self.tr("Debug Script") |
2094 cap = self.tr("Debug Script") |
1982 dlg = StartDialog( |
2095 dlg = StartDialog( |
1983 cap, self.lastUsedVenvName, self.argvHistory, self.wdHistory, |
2096 cap, self.lastUsedVenvName, self.argvHistory, self.wdHistory, |
1984 self.envHistory, self.exceptions, self.ui, 0, |
2097 self.envHistory, self.exceptions, self.ui, 0, |
1985 tracePython=self.tracePython, autoClearShell=self.autoClearShell, |
2098 tracePython=self.tracePython, autoClearShell=self.autoClearShell, |
1986 autoContinue=self.autoContinue, autoFork=self.forkAutomatically, |
2099 autoContinue=self.autoContinue, |
1987 forkChild=self.forkIntoChild) |
2100 enableMultiprocess=self.enableMultiprocess, |
|
2101 multiprocessNoDebugHistory=self.multiprocessNoDebugHistory) |
1988 if dlg.exec() == QDialog.Accepted: |
2102 if dlg.exec() == QDialog.Accepted: |
1989 (lastUsedVenvName, argv, wd, env, exceptions, clearShell, |
2103 (lastUsedVenvName, argv, wd, env, exceptions, clearShell, |
1990 console) = dlg.getData() |
2104 console) = dlg.getData() |
1991 tracePython, autoContinue, forkAutomatically, forkIntoChild = ( |
2105 (tracePython, autoContinue, enableMultiprocess, |
1992 dlg.getDebugData()) |
2106 multiprocessNoDebug) = dlg.getDebugData() |
1993 |
2107 |
1994 if debugProject: |
2108 if debugProject: |
1995 fn = self.project.getMainScript(True) |
2109 fn = self.project.getMainScript(True) |
1996 if fn is None: |
2110 if fn is None: |
1997 E5MessageBox.critical( |
2111 E5MessageBox.critical( |
2010 |
2124 |
2011 # save the info for later use |
2125 # save the info for later use |
2012 self.project.setDbgInfo( |
2126 self.project.setDbgInfo( |
2013 lastUsedVenvName, argv, wd, env, exceptions, self.excList, |
2127 lastUsedVenvName, argv, wd, env, exceptions, self.excList, |
2014 self.excIgnoreList, clearShell, tracePython=tracePython, |
2128 self.excIgnoreList, clearShell, tracePython=tracePython, |
2015 autoContinue=self.autoContinue) |
2129 autoContinue=autoContinue, |
|
2130 enableMultiprocess=enableMultiprocess, |
|
2131 multiprocessNoDebug=multiprocessNoDebug |
|
2132 ) |
2016 |
2133 |
2017 self.lastStartAction = 2 |
2134 self.lastStartAction = 2 |
2018 self.clientType = self.project.getProjectLanguage() |
2135 self.clientType = self.project.getProjectLanguage() |
2019 else: |
2136 else: |
2020 editor = self.viewmanager.activeWindow() |
2137 editor = self.viewmanager.activeWindow() |
2085 self.debugServer.remoteLoad( |
2202 self.debugServer.remoteLoad( |
2086 lastUsedVenvName, fn, argv, wd, env, |
2203 lastUsedVenvName, fn, argv, wd, env, |
2087 autoClearShell=self.autoClearShell, |
2204 autoClearShell=self.autoClearShell, |
2088 tracePython=tracePython, |
2205 tracePython=tracePython, |
2089 autoContinue=autoContinue, forProject=debugProject, |
2206 autoContinue=autoContinue, forProject=debugProject, |
2090 runInConsole=console, autoFork=forkAutomatically, |
2207 runInConsole=console, clientType=self.clientType, |
2091 forkChild=forkIntoChild, clientType=self.clientType, |
2208 enableCallTrace=enableCallTrace, |
2092 enableCallTrace=enableCallTrace) |
2209 enableMultiprocess=enableMultiprocess, |
|
2210 multiprocessNoDebug=multiprocessNoDebug) |
2093 |
2211 |
2094 if ( |
2212 if ( |
2095 self.debugServer.isClientProcessUp() and |
2213 self.debugServer.isClientProcessUp() and |
2096 self.debugServer.getClientType() == self.clientType |
2214 self.debugServer.getClientType() == self.clientType |
2097 ): |
2215 ): |
2102 |
2220 |
2103 if dlg.clearHistories(): |
2221 if dlg.clearHistories(): |
2104 self.setArgvHistory("", clearHistories=True) |
2222 self.setArgvHistory("", clearHistories=True) |
2105 self.setWdHistory("", clearHistories=True) |
2223 self.setWdHistory("", clearHistories=True) |
2106 self.setEnvHistory("", clearHistories=True) |
2224 self.setEnvHistory("", clearHistories=True) |
|
2225 self.setMultiprocessNoDebugHistory("", clearHistories=True) |
2107 elif dlg.historiesModified(): |
2226 elif dlg.historiesModified(): |
2108 argvHistory, wdHistory, envHistory = dlg.getHistories() |
2227 (argvHistory, wdHistory, envHistory, |
|
2228 noDebugHistory) = dlg.getHistories() |
2109 self.setArgvHistory("", history=argvHistory) |
2229 self.setArgvHistory("", history=argvHistory) |
2110 self.setWdHistory("", history=wdHistory) |
2230 self.setWdHistory("", history=wdHistory) |
2111 self.setEnvHistory("", history=envHistory) |
2231 self.setEnvHistory("", history=envHistory) |
|
2232 self.setMultiprocessNoDebugHistory("", history=noDebugHistory) |
2112 |
2233 |
2113 def __doRestart(self): |
2234 def __doRestart(self): |
2114 """ |
2235 """ |
2115 Private slot to handle the restart action to restart the last |
2236 Private slot to handle the restart action to restart the last |
2116 debugged file. |
2237 debugged file. |
2160 if self.lastStartAction in [1, 2]: |
2281 if self.lastStartAction in [1, 2]: |
2161 # Ask the client to send call trace info |
2282 # Ask the client to send call trace info |
2162 enableCallTrace = self.debugViewer.isCallTraceEnabled() |
2283 enableCallTrace = self.debugViewer.isCallTraceEnabled() |
2163 self.debugViewer.clearCallTrace() |
2284 self.debugViewer.clearCallTrace() |
2164 self.debugViewer.setCallTraceToProjectMode(forProject) |
2285 self.debugViewer.setCallTraceToProjectMode(forProject) |
|
2286 multiprocessNoDebug = self.multiprocessNoDebugHistory[0] |
2165 |
2287 |
2166 # Ask the client to debug the new program. |
2288 # Ask the client to debug the new program. |
2167 self.debugServer.remoteLoad( |
2289 self.debugServer.remoteLoad( |
2168 venvName, fn, argv, wd, env, |
2290 venvName, fn, argv, wd, env, |
2169 autoClearShell=self.autoClearShell, |
2291 autoClearShell=self.autoClearShell, |
2170 tracePython=self.tracePython, |
2292 tracePython=self.tracePython, |
2171 autoContinue=self.autoContinue, |
2293 autoContinue=self.autoContinue, |
2172 forProject=forProject, |
2294 forProject=forProject, |
2173 runInConsole=self.runInConsole, |
2295 runInConsole=self.runInConsole, |
2174 autoFork=self.forkAutomatically, |
|
2175 forkChild=self.forkIntoChild, |
|
2176 clientType=self.clientType, |
2296 clientType=self.clientType, |
2177 enableCallTrace=enableCallTrace) |
2297 enableCallTrace=enableCallTrace, |
|
2298 enableMultiprocess=self.enableMultiprocess, |
|
2299 multiprocessNoDebug=multiprocessNoDebug) |
2178 |
2300 |
2179 # Signal that we have started a debugging session |
2301 # Signal that we have started a debugging session |
2180 self.debuggingStarted.emit(fn) |
2302 self.debuggingStarted.emit(fn) |
2181 |
2303 |
2182 elif self.lastStartAction in [3, 4]: |
2304 elif self.lastStartAction in [3, 4]: |
2184 self.debugServer.remoteRun( |
2306 self.debugServer.remoteRun( |
2185 venvName, fn, argv, wd, env, |
2307 venvName, fn, argv, wd, env, |
2186 autoClearShell=self.autoClearShell, |
2308 autoClearShell=self.autoClearShell, |
2187 forProject=forProject, |
2309 forProject=forProject, |
2188 runInConsole=self.runInConsole, |
2310 runInConsole=self.runInConsole, |
2189 autoFork=self.forkAutomatically, |
|
2190 forkChild=self.forkIntoChild, |
|
2191 clientType=self.clientType) |
2311 clientType=self.clientType) |
2192 |
2312 |
2193 elif self.lastStartAction in [5, 6]: |
2313 elif self.lastStartAction in [5, 6]: |
2194 # Ask the client to coverage run the new program. |
2314 # Ask the client to coverage run the new program. |
2195 self.debugServer.remoteCoverage( |
2315 self.debugServer.remoteCoverage( |
2238 self.debuggingStarted.emit(fn) |
2358 self.debuggingStarted.emit(fn) |
2239 |
2359 |
2240 # Initialize the call stack viewer |
2360 # Initialize the call stack viewer |
2241 self.debugViewer.initCallStackViewer(False) |
2361 self.debugViewer.initCallStackViewer(False) |
2242 |
2362 |
2243 def __continue(self): |
2363 def __continue(self, debuggerId=""): |
2244 """ |
2364 """ |
2245 Private method to handle the Continue action. |
2365 Private method to handle the Continue action. |
2246 """ |
2366 |
|
2367 @param debuggerId ID of the debugger backend |
|
2368 @type str |
|
2369 """ |
|
2370 if not debuggerId: |
|
2371 debuggerId = self.getSelectedDebuggerId() |
|
2372 |
2247 self.lastAction = 0 |
2373 self.lastAction = 0 |
2248 self.__enterRemote() |
2374 self.__enterRemote() |
2249 self.debugServer.remoteContinue() |
2375 self.debugServer.remoteContinue(debuggerId) |
2250 |
2376 |
2251 def __specialContinue(self): |
2377 def __specialContinue(self, debuggerId=""): |
2252 """ |
2378 """ |
2253 Private method to handle the Special Continue action. |
2379 Private method to handle the Special Continue action. |
2254 """ |
2380 |
|
2381 @param debuggerId ID of the debugger backend |
|
2382 @type str |
|
2383 """ |
|
2384 if not debuggerId: |
|
2385 debuggerId = self.getSelectedDebuggerId() |
|
2386 |
2255 self.lastAction = 2 |
2387 self.lastAction = 2 |
2256 self.__enterRemote() |
2388 self.__enterRemote() |
2257 self.debugServer.remoteContinue(1) |
2389 self.debugServer.remoteContinue(debuggerId, 1) |
2258 |
2390 |
2259 def __step(self): |
2391 def __step(self, debuggerId=""): |
2260 """ |
2392 """ |
2261 Private method to handle the Step action. |
2393 Private method to handle the Step action. |
2262 """ |
2394 |
|
2395 @param debuggerId ID of the debugger backend |
|
2396 @type str |
|
2397 """ |
|
2398 if not debuggerId: |
|
2399 debuggerId = self.getSelectedDebuggerId() |
|
2400 |
2263 self.lastAction = 1 |
2401 self.lastAction = 1 |
2264 self.__enterRemote() |
2402 self.__enterRemote() |
2265 self.debugServer.remoteStep() |
2403 self.debugServer.remoteStep(debuggerId) |
2266 |
2404 |
2267 def __stepOver(self): |
2405 def __stepOver(self, debuggerId=""): |
2268 """ |
2406 """ |
2269 Private method to handle the Step Over action. |
2407 Private method to handle the Step Over action. |
2270 """ |
2408 |
|
2409 @param debuggerId ID of the debugger backend |
|
2410 @type str |
|
2411 """ |
|
2412 if not debuggerId: |
|
2413 debuggerId = self.getSelectedDebuggerId() |
|
2414 |
2271 self.lastAction = 2 |
2415 self.lastAction = 2 |
2272 self.__enterRemote() |
2416 self.__enterRemote() |
2273 self.debugServer.remoteStepOver() |
2417 self.debugServer.remoteStepOver(debuggerId) |
2274 |
2418 |
2275 def __stepOut(self): |
2419 def __stepOut(self, debuggerId=""): |
2276 """ |
2420 """ |
2277 Private method to handle the Step Out action. |
2421 Private method to handle the Step Out action. |
2278 """ |
2422 |
|
2423 @param debuggerId ID of the debugger backend |
|
2424 @type str |
|
2425 """ |
|
2426 if not debuggerId: |
|
2427 debuggerId = self.getSelectedDebuggerId() |
|
2428 |
2279 self.lastAction = 3 |
2429 self.lastAction = 3 |
2280 self.__enterRemote() |
2430 self.__enterRemote() |
2281 self.debugServer.remoteStepOut() |
2431 self.debugServer.remoteStepOut(debuggerId) |
2282 |
2432 |
2283 def __stepQuit(self): |
2433 def __stepQuit(self, debuggerId=""): |
2284 """ |
2434 """ |
2285 Private method to handle the Step Quit action. |
2435 Private method to handle the Step Quit action. |
2286 """ |
2436 |
|
2437 @param debuggerId ID of the debugger backend |
|
2438 @type str |
|
2439 """ |
|
2440 if not debuggerId: |
|
2441 debuggerId = self.getSelectedDebuggerId() |
|
2442 |
2287 self.lastAction = 4 |
2443 self.lastAction = 4 |
2288 self.__enterRemote() |
2444 self.__enterRemote() |
2289 self.debugServer.remoteStepQuit() |
2445 self.debugServer.remoteStepQuit(debuggerId) |
2290 self.__resetUI() |
2446 self.__resetUI() |
2291 |
2447 |
2292 def __runToCursor(self): |
2448 def __runToCursor(self, debuggerId=""): |
2293 """ |
2449 """ |
2294 Private method to handle the Run to Cursor action. |
2450 Private method to handle the Run to Cursor action. |
2295 """ |
2451 |
|
2452 @param debuggerId ID of the debugger backend |
|
2453 @type str |
|
2454 """ |
|
2455 if not debuggerId: |
|
2456 debuggerId = self.getSelectedDebuggerId() |
|
2457 |
2296 self.lastAction = 0 |
2458 self.lastAction = 0 |
2297 aw = self.viewmanager.activeWindow() |
2459 aw = self.viewmanager.activeWindow() |
2298 line = aw.getCursorPosition()[0] + 1 |
2460 line = aw.getCursorPosition()[0] + 1 |
2299 self.__enterRemote() |
2461 self.__enterRemote() |
2300 self.debugServer.remoteBreakpoint( |
2462 self.debugServer.remoteBreakpoint( |
|
2463 self.getSelectedDebuggerId(), |
2301 aw.getFileName(), line, 1, None, 1) |
2464 aw.getFileName(), line, 1, None, 1) |
2302 self.debugServer.remoteContinue() |
2465 self.debugServer.remoteContinue(debuggerId) |
2303 |
2466 |
2304 def __moveInstructionPointer(self): |
2467 def __runUntil(self, debuggerId=""): |
2305 """ |
2468 """ |
2306 Private method to move the instruction pointer to a different line. |
2469 Private method to handle the Run Until action. |
2307 """ |
2470 |
|
2471 @param debuggerId ID of the debugger backend |
|
2472 @type str |
|
2473 """ |
|
2474 if not debuggerId: |
|
2475 debuggerId = self.getSelectedDebuggerId() |
|
2476 |
2308 self.lastAction = 0 |
2477 self.lastAction = 0 |
2309 aw = self.viewmanager.activeWindow() |
2478 aw = self.viewmanager.activeWindow() |
2310 line = aw.getCursorPosition()[0] + 1 |
2479 line = aw.getCursorPosition()[0] + 1 |
2311 self.debugServer.remoteMoveIP(line) |
2480 self.__enterRemote() |
|
2481 self.debugServer.remoteContinueUntil(debuggerId, line) |
|
2482 |
|
2483 def __moveInstructionPointer(self, debuggerId=""): |
|
2484 """ |
|
2485 Private method to move the instruction pointer to a different line. |
|
2486 |
|
2487 @param debuggerId ID of the debugger backend |
|
2488 @type str |
|
2489 """ |
|
2490 if not debuggerId: |
|
2491 debuggerId = self.getSelectedDebuggerId() |
|
2492 |
|
2493 self.lastAction = 0 |
|
2494 aw = self.viewmanager.activeWindow() |
|
2495 line = aw.getCursorPosition()[0] + 1 |
|
2496 self.debugServer.remoteMoveIP(debuggerId, line) |
2312 |
2497 |
2313 def __enterRemote(self): |
2498 def __enterRemote(self): |
2314 """ |
2499 """ |
2315 Private method to update the user interface. |
2500 Private method to update the user interface. |
2316 |
2501 |
2327 Public method to get a list of all actions. |
2512 Public method to get a list of all actions. |
2328 |
2513 |
2329 @return list of all actions (list of E5Action) |
2514 @return list of all actions (list of E5Action) |
2330 """ |
2515 """ |
2331 return self.actions[:] |
2516 return self.actions[:] |
|
2517 |
|
2518 def getSelectedDebuggerId(self): |
|
2519 """ |
|
2520 Public method to get the currently selected debugger ID. |
|
2521 |
|
2522 @return selected debugger ID |
|
2523 @rtype str |
|
2524 """ |
|
2525 return self.debugViewer.getSelectedDebuggerId() |
|
2526 |
|
2527 def setDebugActionsEnabled(self, enable): |
|
2528 """ |
|
2529 Public method to set the enabled state of the debug actions. |
|
2530 |
|
2531 @param enable enable state to be set |
|
2532 @type bool |
|
2533 """ |
|
2534 self.debugActGrp.setEnabled(enable) |
|
2535 |
|
2536 def setMultiprocessNoDebugHistory(self, noDebugList, clearHistories=False, |
|
2537 history=None): |
|
2538 """ |
|
2539 Public slot to initialize the no debug list history. |
|
2540 |
|
2541 @param noDebugList whitespace separated list of programs not to be |
|
2542 debugged |
|
2543 @type str |
|
2544 @param clearHistories flag indicating, that the list should be cleared |
|
2545 @type bool |
|
2546 @param history list of history entries to be set |
|
2547 @type list of str |
|
2548 """ |
|
2549 if clearHistories: |
|
2550 del self.multiprocessNoDebugHistory[1:] |
|
2551 elif history is not None: |
|
2552 self.multiprocessNoDebugHistory = history[:] |
|
2553 else: |
|
2554 if noDebugList in self.multiprocessNoDebugHistory: |
|
2555 self.multiprocessNoDebugHistory.remove(noDebugList) |
|
2556 self.multiprocessNoDebugHistory.insert(0, noDebugList) |
|
2557 |
|
2558 def setEnableMultiprocess(self, enableMultiprocess): |
|
2559 """ |
|
2560 Public slot to initialize the enableMultiprocess flag. |
|
2561 |
|
2562 @param enableMultiprocess flag indicating, that the debugger should be |
|
2563 run in multi process mode |
|
2564 @type bool |
|
2565 """ |
|
2566 self.enableMultiprocess = enableMultiprocess |