Continued with the multiprocess debugger. multi_processing

Tue, 28 Jan 2020 19:41:51 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Tue, 28 Jan 2020 19:41:51 +0100
branch
multi_processing
changeset 7374
5401ae8ddaa1
parent 7373
d036d72f457c
child 7375
af2500ced7e0

Continued with the multiprocess debugger.

eric6/DebugClients/Python/DebugClientBase.py file | annotate | diff | comparison | revisions
eric6/Debugger/DebugServer.py file | annotate | diff | comparison | revisions
eric6/Debugger/DebugUI.py file | annotate | diff | comparison | revisions
eric6/Debugger/DebugViewer.py file | annotate | diff | comparison | revisions
eric6/Debugger/DebuggerInterfacePython.py file | annotate | diff | comparison | revisions
--- a/eric6/DebugClients/Python/DebugClientBase.py	Mon Jan 27 19:50:40 2020 +0100
+++ b/eric6/DebugClients/Python/DebugClientBase.py	Tue Jan 28 19:41:51 2020 +0100
@@ -392,12 +392,24 @@
                 params["variable"], params["frameNumber"],
                 params["scope"], params["filters"])
         
+        elif method == "RequestStack":
+            stack = self.mainThread.getStack()
+            self.sendResponseLine(stack)
+        
         elif method == "RequestThreadList":
             self.dumpThreadList()
         
         elif method == "RequestThreadSet":
-            if params["threadID"] in self.threads:
-                self.setCurrentThread(params["threadID"])
+            if params["threadID"] == -1:
+                # -1 is indication for the main thread
+                threadId = -1
+                for thread in self.threads.values():
+                    if thread.name == "MainThread":
+                        threadId = thread.id
+            else:
+                threadId = params["threadID"]
+            if threadId in self.threads:
+                self.setCurrentThread(threadId)
                 self.sendJsonCommand("ResponseThreadSet", {})
                 stack = self.currentThread.getStack()
                 self.sendJsonCommand("ResponseStack", {
--- a/eric6/Debugger/DebugServer.py	Mon Jan 27 19:50:40 2020 +0100
+++ b/eric6/Debugger/DebugServer.py	Tue Jan 28 19:41:51 2020 +0100
@@ -114,6 +114,8 @@
         toFunction)
     @signal appendStdout(msg) emitted when a passive debug connection is
         established or lost
+    @signal clientDebuggerIds(debuggerIds) emitted to give the list of IDs of
+        attached debugger backends
     """
     clientClearBreak = pyqtSignal(str, int)
     clientClearWatch = pyqtSignal(str)
@@ -140,6 +142,7 @@
     clientCapabilities = pyqtSignal(int, str, str)
     clientCompletionList = pyqtSignal(list, str)
     clientInterpreterChanged = pyqtSignal(str)
+    clientDebuggerIds = pyqtSignal(list)
     utDiscovered = pyqtSignal(list, str, str)
     utPrepared = pyqtSignal(int, str, str)
     utStartTest = pyqtSignal(str, str)
@@ -1230,30 +1233,52 @@
         self.debuggerInterface.remoteRawInput(s)
         self.clientRawInputSent.emit()
         
-    def remoteThreadList(self):
+    def remoteThreadList(self, debuggerId=""):
         """
         Public method to request the list of threads from the client.
+        
+        @param debuggerId ID of the debugger backend
+        @type str
         """
-        self.debuggerInterface.remoteThreadList()
+        self.debuggerInterface.remoteThreadList(debuggerId=debuggerId)
         
-    def remoteSetThread(self, tid):
+    def remoteSetThread(self, tid, debuggerId=""):
         """
         Public method to request to set the given thread as current thread.
         
-        @param tid id of the thread (integer)
+        @param tid id of the thread
+        @type int
+        @param debuggerId ID of the debugger backend
+        @type str
+        """
+        self.debuggerInterface.remoteSetThread(tid, debuggerId=debuggerId)
+    
+    def remoteClientStack(self, debuggerId=""):
         """
-        self.debuggerInterface.remoteSetThread(tid)
+        Public method to request the stack of the main thread.
         
-    def remoteClientVariables(self, scope, filterList, framenr=0):
+        @param debuggerId ID of the debugger backend
+        @type str
+        """
+        self.debuggerInterface.remoteClientStack(debuggerId=debuggerId)
+    
+    def remoteClientVariables(self, scope, filterList, framenr=0,
+                              debuggerId=""):
         """
         Public method to request the variables of the debugged program.
         
         @param scope the scope of the variables (0 = local, 1 = global)
-        @param filterList list of variable types to filter out (list of int)
-        @param framenr framenumber of the variables to retrieve (int)
+        @type int
+        @param filterList list of variable types to filter out
+        @type list of int
+        @param framenr framenumber of the variables to retrieve
+        @type int
+        @param debuggerId ID of the debugger backend
+        @type str
         """
         self.debuggerInterface.remoteClientVariables(
-            scope, filterList, framenr, self.__maxVariableSize)
+            scope, filterList, framenr, self.__maxVariableSize,
+            debuggerId=debuggerId)
         
     def remoteClientVariable(self, scope, filterList, var, framenr=0):
         """
@@ -1680,7 +1705,7 @@
         self.callTraceInfo.emit(
             isCall, fromFile, fromLine, fromFunction,
             toFile, toLine, toFunction)
-        
+    
     def clientUtDiscovered(self, testCases, exceptionType, exceptionValue):
         """
         Public method to process the client unittest discover info.
@@ -1862,3 +1887,26 @@
         @type bool
         """
         self.debugging = on
+    
+    def signalClientDebuggerIds(self, debuggerIds):
+        """
+        Public method to signal the receipt of a new debugger ID.
+        
+        This signal indicates, that a new debugger backend has connected.
+        
+        @param debuggerIds list of IDs of the connected debugger backends
+        @type list of str
+        """
+        self.clientDebuggerIds.emit(debuggerIds)
+    
+    def getDebuggerIds(self):
+        """
+        Public method to return the IDs of the connected debugger backends.
+        
+        @return list of connected debugger backend IDs
+        @rtype list of str
+        """
+        if self.debuggerInterface:
+            return self.debuggerInterface.getDebuggerIds()
+        else:
+            return []
--- a/eric6/Debugger/DebugUI.py	Mon Jan 27 19:50:40 2020 +0100
+++ b/eric6/Debugger/DebugUI.py	Tue Jan 28 19:41:51 2020 +0100
@@ -138,6 +138,7 @@
         debugServer.clientThreadSet.connect(self.__clientThreadSet)
         
         debugServer.clientThreadList.connect(debugViewer.showThreadList)
+        debugServer.clientDebuggerIds.connect(debugViewer.showDebuggersList)
         
         # Connect the signals emitted by the viewmanager
         vm.editorOpened.connect(self.__editorOpened)
@@ -1270,11 +1271,14 @@
                 self.tr('The program being debugged has terminated'
                         ' unexpectedly.'))
         
-    def __getThreadList(self):
+    def __getThreadList(self, debuggerId=""):
         """
         Private method to get the list of threads from the client.
+        
+        @param debuggerId ID of the debugger backend
+        @type str
         """
-        self.debugServer.remoteThreadList()
+        self.debugServer.remoteThreadList(debuggerId=debuggerId)
         
     def __clientThreadSet(self):
         """
@@ -1282,23 +1286,27 @@
         """
         self.debugServer.remoteClientVariables(0, self.localsVarFilter)
         
-    def __getClientVariables(self):
+    def __getClientVariables(self, debuggerId=""):
         """
         Private method to request the global and local variables.
         
         In the first step, the global variables are requested from the client.
         Once these have been received, the local variables are requested.
         This happens in the method '__clientVariables'.
+        
+        @param debuggerId ID of the debugger backend
+        @type str
         """
         # get globals first
-        self.debugServer.remoteClientVariables(1, self.globalsVarFilter)
+        self.debugServer.remoteClientVariables(1, self.globalsVarFilter,
+                                               debuggerId=debuggerId)
         # the local variables are requested once we have received the globals
         
     def __clientVariables(self, scope, variables):
         """
         Private method to write the clients variables to the user interface.
         
-        @param scope scope of the variables (-1 = empty global, 1 = global,
+        @param scope scope of the variables (-1 = empty locals, 1 = global,
             0 = local)
         @param variables the list of variables from the client
         """
@@ -2325,3 +2333,15 @@
         @return list of all actions (list of E5Action)
         """
         return self.actions[:]
+    
+    def getDebuggerData(self, debuggerId):
+        """
+        Public method to refresh the debugging data of a specific debugger
+        backend.
+        
+        @param debuggerId ID of the debugger backend
+        @type str
+        """
+        self.debugServer.remoteClientStack(debuggerId)
+        self.__getThreadList(debuggerId)
+        self.__getClientVariables(debuggerId)
--- a/eric6/Debugger/DebugViewer.py	Mon Jan 27 19:50:40 2020 +0100
+++ b/eric6/Debugger/DebugViewer.py	Tue Jan 28 19:41:51 2020 +0100
@@ -239,6 +239,18 @@
         
         self.__threadList.currentItemChanged.connect(self.__threadSelected)
         
+        # add the debugger viewer
+        self.__debuggersLayout = QHBoxLayout(self)
+        self.__debuggersLayout.addWidget(QLabel(self.tr("Debuggers:")))
+        self.__debuggersCombo = QComboBox(self)
+        self.__debuggersCombo.setSizePolicy(
+            QSizePolicy.Expanding, QSizePolicy.Fixed)
+        self.__debuggersLayout.addWidget(self.__debuggersCombo)
+        self.__mainLayout.addLayout(self.__debuggersLayout)
+        
+        self.__debuggersCombo.currentTextChanged.connect(
+            self.__debuggerSelected)
+
         self.__mainLayout.setStretchFactor(self.__tabWidget, 5)
         self.__mainLayout.setStretchFactor(self.__threadList, 1)
         
@@ -281,6 +293,7 @@
         self.__threadList.clear()
         self.__tabWidget.setCurrentWidget(self.glvWidget)
         self.breakpointViewer.handleResetUI()
+        self.__debuggersCombo.clear()
         
     def initCallStackViewer(self, projectMode):
         """
@@ -396,12 +409,14 @@
         
         @param frmnr frame number (0 is the current frame) (int)
         """
-        self.framenr = frmnr
-        if self.debugServer.isDebugging():
-            self.debugServer.remoteClientVariables(0, self.localsFilter, frmnr)
-        
-        if self.__autoViewSource:
-            self.__showSource()
+        if frmnr >= 0:
+            self.framenr = frmnr
+            if self.debugServer.isDebugging():
+                self.debugServer.remoteClientVariables(
+                    0, self.localsFilter, frmnr)
+            
+            if self.__autoViewSource:
+                self.__showSource()
         
     def setGlobalsFilter(self):
         """
@@ -499,3 +514,47 @@
         """
         if frameNo >= 0:
             self.stackComboBox.setCurrentIndex(frameNo)
+    
+    def __debuggerSelected(self, debuggerId):
+        """
+        Private slot to handle the selection of a debugger backend ID.
+        
+        @param debuggerId ID of the selected debugger backend
+        @type str
+        """
+        if debuggerId:
+            self.globalsViewer.handleResetUI()
+            self.localsViewer.handleResetUI()
+            self.currentStack = None
+            self.stackComboBox.clear()
+            self.__threadList.clear()
+            
+            self.debugUI.getDebuggerData(debuggerId)
+    
+    def showDebuggersList(self, debuggerIds):
+        """
+        Public slot to receive the list of debugger backend IDs.
+        
+        @param debuggerIds list of debugger backend IDs
+        @type list of str
+        """
+        block = self.__debuggersCombo.blockSignals(True)
+        
+        currentDebuggerId = self.__debuggersCombo.currentText()
+        self.__debuggersCombo.clear()
+        self.__debuggersCombo.addItems(debuggerIds)
+        if currentDebuggerId:
+            self.__debuggersCombo.setCurrentText(currentDebuggerId)
+        else:
+            self.__debuggersCombo.setCurrentIndex(0)
+        
+        self.__debuggersCombo.blockSignals(block)
+    
+    def getSelectedDebuggerId(self):
+        """
+        Public method to get the currently selected debugger ID.
+        
+        @return selected debugger ID
+        @rtype str
+        """
+        return self.__debuggersCombo.currentText()
--- a/eric6/Debugger/DebuggerInterfacePython.py	Mon Jan 27 19:50:40 2020 +0100
+++ b/eric6/Debugger/DebuggerInterfacePython.py	Tue Jan 28 19:41:51 2020 +0100
@@ -528,6 +528,18 @@
         if sock in self.__pendingConnections:
             self.__connections[debuggerId] = sock
             self.__pendingConnections.remove(sock)
+            
+            self.debugServer.signalClientDebuggerIds(
+                sorted(self.__connections.keys()))
+    
+    def getDebuggerIds(self):
+        """
+        Public method to return the IDs of the connected debugger backends.
+        
+        @return list of connected debugger backend IDs
+        @rtype list of str
+        """
+        return sorted(self.__connections.keys())
     
     def flush(self):
         """
@@ -837,23 +849,39 @@
             "input": s,
         })
     
-    def remoteThreadList(self):
+    def remoteThreadList(self, debuggerId=""):
         """
         Public method to request the list of threads from the client.
+        
+        @param debuggerId ID of the debugger backend
+        @type str
         """
-        self.__sendJsonCommand("RequestThreadList", {})
+        self.__sendJsonCommand("RequestThreadList", {}, debuggerId=debuggerId)
         
-    def remoteSetThread(self, tid):
+    def remoteSetThread(self, tid, debuggerId=""):
         """
         Public method to request to set the given thread as current thread.
         
-        @param tid id of the thread (integer)
+        @param tid id of the thread
+        @type int
+        @param debuggerId ID of the debugger backend
+        @type str
         """
         self.__sendJsonCommand("RequestThreadSet", {
             "threadID": tid,
-        })
+        }, debuggerId=debuggerId)
+    
+    def remoteClientStack(self, debuggerId=""):
+        """
+        Public method to request the stack of the main thread.
         
-    def remoteClientVariables(self, scope, filterList, framenr=0, maxSize=0):
+        @param debuggerId ID of the debugger backend
+        @type str
+        """
+        self.__sendJsonCommand("RequestStack", {}, debuggerId=debuggerId)
+    
+    def remoteClientVariables(self, scope, filterList, framenr=0, maxSize=0,
+                              debuggerId=""):
         """
         Public method to request the variables of the debugged program.
         
@@ -867,13 +895,15 @@
             be shown. If it is bigger than that, a 'too big' indication will
             be given (@@TOO_BIG_TO_SHOW@@).
         @type int
+        @param debuggerId ID of the debugger backend
+        @type str
         """
         self.__sendJsonCommand("RequestVariables", {
             "frameNumber": framenr,
             "scope": scope,
             "filters": filterList,
             "maxSize": maxSize,
-        })
+        }, debuggerId=debuggerId)
     
     def remoteClientVariable(self, scope, filterList, var, framenr=0,
                              maxSize=0):

eric ide

mercurial