eric6/Debugger/DebugUI.py

branch
maintenance
changeset 8043
0acf98cd089a
parent 7924
8a96736d465e
parent 8008
ae9ab1e150dc
child 8142
43248bafe9b2
equal deleted inserted replaced
7991:866adc8c315b 8043:0acf98cd089a
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)
133 self.__clientBreakConditionError) 142 self.__clientBreakConditionError)
134 debugServer.clientWatchConditionError.connect( 143 debugServer.clientWatchConditionError.connect(
135 self.__clientWatchConditionError) 144 self.__clientWatchConditionError)
136 debugServer.passiveDebugStarted.connect(self.__passiveDebugStarted) 145 debugServer.passiveDebugStarted.connect(self.__passiveDebugStarted)
137 debugServer.clientThreadSet.connect(self.__clientThreadSet) 146 debugServer.clientThreadSet.connect(self.__clientThreadSet)
138 147 debugServer.clientDebuggerId.connect(self.__clientDebuggerId)
139 debugServer.clientThreadList.connect(debugViewer.showThreadList)
140 148
141 # Connect the signals emitted by the viewmanager 149 # Connect the signals emitted by the viewmanager
142 vm.editorOpened.connect(self.__editorOpened) 150 vm.editorOpened.connect(self.__editorOpened)
143 vm.lastEditorClosed.connect(self.__lastEditorClosed) 151 vm.lastEditorClosed.connect(self.__lastEditorClosed)
144 vm.checkActions.connect(self.__checkActions) 152 vm.checkActions.connect(self.__checkActions)
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"),
910 Public method to clear the various debug histories. 953 Public method to clear the various debug histories.
911 """ 954 """
912 self.argvHistory = [] 955 self.argvHistory = []
913 self.wdHistory = [] 956 self.wdHistory = []
914 self.envHistory = [] 957 self.envHistory = []
958 self.multiprocessNoDebugHistory = []
915 959
916 Preferences.Prefs.settings.setValue( 960 Preferences.Prefs.settings.setValue(
917 'DebugInfo/ArgumentsHistory', self.argvHistory) 961 'DebugInfo/ArgumentsHistory', self.argvHistory)
918 Preferences.Prefs.settings.setValue( 962 Preferences.Prefs.settings.setValue(
919 'DebugInfo/WorkingDirectoryHistory', self.wdHistory) 963 'DebugInfo/WorkingDirectoryHistory', self.wdHistory)
920 Preferences.Prefs.settings.setValue( 964 Preferences.Prefs.settings.setValue(
921 'DebugInfo/EnvironmentHistory', self.envHistory) 965 'DebugInfo/EnvironmentHistory', self.envHistory)
966 Preferences.Prefs.settings.setValue(
967 'DebugInfo/MultiprocessNoDebugHistory',
968 self.multiprocessNoDebugHistory)
922 969
923 def shutdown(self): 970 def shutdown(self):
924 """ 971 """
925 Public method to perform shutdown actions. 972 Public method to perform shutdown actions.
926 """ 973 """
948 Preferences.Prefs.settings.setValue( 995 Preferences.Prefs.settings.setValue(
949 'DebugInfo/TracePython', self.tracePython) 996 'DebugInfo/TracePython', self.tracePython)
950 Preferences.Prefs.settings.setValue( 997 Preferences.Prefs.settings.setValue(
951 'DebugInfo/AutoContinue', self.autoContinue) 998 'DebugInfo/AutoContinue', self.autoContinue)
952 Preferences.Prefs.settings.setValue( 999 Preferences.Prefs.settings.setValue(
953 'DebugInfo/ForkAutomatically', self.forkAutomatically) 1000 'DebugInfo/EnableMultiprocess', self.enableMultiprocess)
954 Preferences.Prefs.settings.setValue( 1001 Preferences.Prefs.settings.setValue(
955 'DebugInfo/ForkIntoChild', self.forkIntoChild) 1002 'DebugInfo/MultiprocessNoDebugHistory',
1003 self.multiprocessNoDebugHistory)
956 1004
957 def shutdownServer(self): 1005 def shutdownServer(self):
958 """ 1006 """
959 Public method to shut down the debug server. 1007 Public method to shut down the debug server.
960 1008
963 @return always true 1011 @return always true
964 """ 1012 """
965 self.debugServer.shutdownServer() 1013 self.debugServer.shutdownServer()
966 return True 1014 return True
967 1015
968 def __resetUI(self): 1016 def __resetUI(self, fullReset=True):
969 """ 1017 """
970 Private slot to reset the user interface. 1018 Private slot to reset the user interface.
1019
1020 @param fullReset flag indicating a full reset is required
1021 @type bool
971 """ 1022 """
972 self.lastAction = -1 1023 self.lastAction = -1
973 self.debugActGrp.setEnabled(False) 1024 self.debugActGrp.setEnabled(False)
1025 self.__clientDebuggerIds.clear()
1026
974 if not self.passive: 1027 if not self.passive:
975 if self.editorOpen: 1028 if self.editorOpen:
976 editor = self.viewmanager.activeWindow() 1029 editor = self.viewmanager.activeWindow()
977 else: 1030 else:
978 editor = None 1031 editor = None
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
1241 @param lineNo line number of the syntax error position 1318 @param lineNo line number of the syntax error position
1242 @type int 1319 @type int
1243 @param funcName name of the function causing the signal 1320 @param funcName name of the function causing the signal
1244 @type str 1321 @type str
1245 @param funcArgs function arguments 1322 @param funcArgs function arguments
1323 @type str
1324 @param debuggerId ID of the debugger backend
1246 @type str 1325 @type str
1247 """ 1326 """
1248 self.ui.raise_() 1327 self.ui.raise_()
1249 self.ui.activateWindow() 1328 self.ui.activateWindow()
1250 QApplication.processEvents() 1329 QApplication.processEvents()
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 """
1597 doNotStart = True 1712 doNotStart = True
1598 1713
1599 # save the info for later use 1714 # save the info for later use
1600 self.project.setDbgInfo( 1715 self.project.setDbgInfo(
1601 lastUsedVenvName, argv, wd, env, exceptions, self.excList, 1716 lastUsedVenvName, argv, wd, env, exceptions, self.excList,
1602 self.excIgnoreList, clearShell) 1717 self.excIgnoreList, clearShell
1718 )
1603 1719
1604 self.lastStartAction = 6 1720 self.lastStartAction = 6
1605 self.clientType = self.project.getProjectLanguage() 1721 self.clientType = self.project.getProjectLanguage()
1606 else: 1722 else:
1607 editor = self.viewmanager.activeWindow() 1723 editor = self.viewmanager.activeWindow()
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):
1732 doNotStart = True 1849 doNotStart = True
1733 1850
1734 # save the info for later use 1851 # save the info for later use
1735 self.project.setDbgInfo( 1852 self.project.setDbgInfo(
1736 lastUsedVenvName, argv, wd, env, exceptions, self.excList, 1853 lastUsedVenvName, argv, wd, env, exceptions, self.excList,
1737 self.excIgnoreList, clearShell) 1854 self.excIgnoreList, clearShell
1855 )
1738 1856
1739 self.lastStartAction = 8 1857 self.lastStartAction = 8
1740 self.clientType = self.project.getProjectLanguage() 1858 self.clientType = self.project.getProjectLanguage()
1741 else: 1859 else:
1742 editor = self.viewmanager.activeWindow() 1860 editor = self.viewmanager.activeWindow()
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(
1869 doNotStart = True 1985 doNotStart = True
1870 1986
1871 # save the info for later use 1987 # save the info for later use
1872 self.project.setDbgInfo( 1988 self.project.setDbgInfo(
1873 lastUsedVenvName, argv, wd, env, exceptions, self.excList, 1989 lastUsedVenvName, argv, wd, env, exceptions, self.excList,
1874 self.excIgnoreList, clearShell) 1990 self.excIgnoreList, clearShell
1991 )
1875 1992
1876 self.lastStartAction = 4 1993 self.lastStartAction = 4
1877 self.clientType = self.project.getProjectLanguage() 1994 self.clientType = self.project.getProjectLanguage()
1878 else: 1995 else:
1879 editor = self.viewmanager.activeWindow() 1996 editor = self.viewmanager.activeWindow()
1912 self.autoClearShell = clearShell 2029 self.autoClearShell = clearShell
1913 2030
1914 # Save the run in console flag 2031 # Save the run in console flag
1915 self.runInConsole = console 2032 self.runInConsole = console
1916 2033
1917 # Save the forking flags
1918 self.forkAutomatically = forkAutomatically
1919 self.forkIntoChild = forkIntoChild
1920
1921 # Hide all error highlights 2034 # Hide all error highlights
1922 self.viewmanager.unhighlight() 2035 self.viewmanager.unhighlight()
1923 2036
1924 if not doNotStart: 2037 if not doNotStart:
1925 if runProject and self.project.getProjectType() in [ 2038 if runProject and self.project.getProjectType() in [
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()
2058 self.runInConsole = console 2175 self.runInConsole = console
2059 2176
2060 # Save the auto continue flag 2177 # Save the auto continue flag
2061 self.autoContinue = autoContinue 2178 self.autoContinue = autoContinue
2062 2179
2063 # Save the forking flags 2180 # Save the multiprocess debugging data
2064 self.forkAutomatically = forkAutomatically 2181 self.enableMultiprocess = enableMultiprocess
2065 self.forkIntoChild = forkIntoChild 2182 self.setMultiprocessNoDebugHistory(multiprocessNoDebug)
2066 2183
2067 # Hide all error highlights 2184 # Hide all error highlights
2068 self.viewmanager.unhighlight() 2185 self.viewmanager.unhighlight()
2069 2186
2070 if not doNotStart: 2187 if not doNotStart:
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

eric ide

mercurial