Debugger: fixed an issue related to multiprocessing on Windows and macOS because these use the 'spawn' method.

Fri, 01 Jan 2021 16:25:30 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Fri, 01 Jan 2021 16:25:30 +0100
changeset 7932
c4c6b2784eec
parent 7931
a761160bfde9
child 7933
ca1b44d522b9

Debugger: fixed an issue related to multiprocessing on Windows and macOS because these use the 'spawn' method.

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	Thu Dec 31 17:42:50 2020 +0100
+++ b/eric6/DebugClients/Python/DebugClientBase.py	Fri Jan 01 16:25:30 2021 +0100
@@ -1281,18 +1281,12 @@
             remoteAddress = remoteAddress.split("@@i")[0]
         sock = socket.create_connection((remoteAddress, port))
         
-        if not name:
-            name = "main"
-        self.__debuggerId = "{0}-{1}-{2}".format(
-            socket.gethostname(), os.getpid(), name
-        )
+        stdinName = sys.stdin.name
+        # Special case if in a multiprocessing.Process
+        if isinstance(stdinName, int):
+            stdinName = '<stdin>'
         
-        name = sys.stdin.name
-        # Special case if in a multiprocessing.Process
-        if isinstance(name, int):
-            name = '<stdin>'
-        
-        self.readstream = AsyncFile(sock, sys.stdin.mode, name)
+        self.readstream = AsyncFile(sock, sys.stdin.mode, stdinName)
         self.writestream = AsyncFile(sock, sys.stdout.mode, sys.stdout.name)
         self.errorstream = AsyncFile(sock, sys.stderr.mode, sys.stderr.name)
         
@@ -1305,6 +1299,12 @@
         # attach to the main thread here
         self.attachThread(mainThread=True)
         
+        if not name:
+            name = "main"
+        self.__debuggerId = "{0}/{1}/{2}".format(
+            socket.gethostname(), os.getpid(), name
+        )
+        
         self.sendDebuggerId(self.__debuggerId)
 
     def __unhandled_exception(self, exctype, excval, exctb):
--- a/eric6/Debugger/DebugServer.py	Thu Dec 31 17:42:50 2020 +0100
+++ b/eric6/Debugger/DebugServer.py	Fri Jan 01 16:25:30 2021 +0100
@@ -67,6 +67,8 @@
     @signal clientSignal(message, filename, linenumber, function name,
         function arguments, debuggerId) emitted after a signal has been
         generated on the client side
+    @signal clientDisconnected(str) emitted after a debug client has
+        disconnected (i.e. closed the network socket)
     @signal clientExit(str, int, str, bool, str) emitted after the client has
         exited giving the program name, the exit status, an exit message, an
         indication to be quiet and the ID of the exited client
@@ -140,6 +142,7 @@
     clientException = pyqtSignal(str, str, list, str)
     clientSyntaxError = pyqtSignal(str, str, int, int, str)
     clientSignal = pyqtSignal(str, str, int, str, str, str)
+    clientDisconnected = pyqtSignal(str)
     clientExit = pyqtSignal(str, int, str, bool, str)
     lastClientExited = pyqtSignal()
     clientBreakConditionError = pyqtSignal(str, int, str)
@@ -1810,6 +1813,16 @@
             self.clientSignal.emit(message, filename, lineNo,
                                    funcName, funcArgs, debuggerId)
     
+    def signalClientDisconnected(self, debuggerId):
+        """
+        Public method to send a signal when a debug client has closed its
+        connection.
+        
+        @param debuggerId ID of the debugger backend
+        @type str
+        """
+        self.clientDisconnected.emit(debuggerId)
+    
     def signalClientExit(self, program, status, message, debuggerId):
         """
         Public method to process the client exit status.
--- a/eric6/Debugger/DebugUI.py	Thu Dec 31 17:42:50 2020 +0100
+++ b/eric6/Debugger/DebugUI.py	Fri Jan 01 16:25:30 2021 +0100
@@ -128,6 +128,7 @@
         # Connect the signals emitted by the debug-server
         debugServer.clientGone.connect(self.__clientGone)
         debugServer.clientLine.connect(self.__clientLine)
+        debugServer.clientDisconnected.connect(self.__clientDisconnected)
         debugServer.clientExit.connect(self.__clientExit)
         debugServer.lastClientExited.connect(self.__lastClientExited)
         debugServer.clientSyntaxError.connect(self.__clientSyntaxError)
@@ -1073,10 +1074,25 @@
 
         self.debugActGrp.setEnabled(True)
     
+    @pyqtSlot(str)
+    def __clientDisconnected(self, debuggerId):
+        """
+        Private slot to handle a debug client disconnecting its control
+        socket.
+        
+        @param debuggerId ID of the debugger backend
+        @type str
+        """
+        self.__clientDebuggerIds.discard(debuggerId)
+        
+        if len(self.__clientDebuggerIds) == 0:
+            self.viewmanager.exit()
+            self.__resetUI(fullReset=False)
+    
     @pyqtSlot(str, int, str, bool, str)
     def __clientExit(self, program, status, message, quiet, debuggerId):
         """
-        Private method to handle the debugged program terminating.
+        Private slot to handle the debugged program terminating.
         
         @param program name of the exited program
         @type str
@@ -1089,11 +1105,7 @@
         @param debuggerId ID of the debugger backend
         @type str
         """
-        self.__clientDebuggerIds.discard(debuggerId)
-        
-        if len(self.__clientDebuggerIds) == 0:
-            self.viewmanager.exit()
-            self.__resetUI(fullReset=False)
+        self.__clientDisconnected(debuggerId)
         
         if not quiet:
             if not program:
--- a/eric6/Debugger/DebugViewer.py	Thu Dec 31 17:42:50 2020 +0100
+++ b/eric6/Debugger/DebugViewer.py	Fri Jan 01 16:25:30 2021 +0100
@@ -300,6 +300,8 @@
             self.__clientException)
         self.debugServer.clientExit.connect(
             self.__clientExit)
+        self.debugServer.clientDisconnected.connect(
+            self.__removeDebugger)
         
         self.debugServer.clientException.connect(
             self.exceptionLogger.addException)
--- a/eric6/Debugger/DebuggerInterfacePython.py	Thu Dec 31 17:42:50 2020 +0100
+++ b/eric6/Debugger/DebuggerInterfacePython.py	Fri Jan 01 16:25:30 2021 +0100
@@ -578,6 +578,7 @@
                     self.__master = None
                 if debuggerId in self.__autoContinued:
                     self.__autoContinued.remove(debuggerId)
+                self.debugServer.signalClientDisconnected(debuggerId)
                 break
         else:
             if sock in self.__pendingConnections:

eric ide

mercurial