Collect all running threads, even if they were not started by the debug client. debugger speed

Sun, 09 Oct 2016 22:22:36 +0200

author
T.Rzepka <Tobias.Rzepka@gmail.com>
date
Sun, 09 Oct 2016 22:22:36 +0200
branch
debugger speed
changeset 5222
6548dc1bfd48
parent 5221
960afd19c1b6
child 5228
4332a6751b14

Collect all running threads, even if they were not started by the debug client.

DebugClients/Python/DebugBase.py file | annotate | diff | comparison | revisions
DebugClients/Python/ThreadExtension.py file | annotate | diff | comparison | revisions
--- a/DebugClients/Python/DebugBase.py	Sat Oct 08 21:01:32 2016 +0200
+++ b/DebugClients/Python/DebugBase.py	Sun Oct 09 22:22:36 2016 +0200
@@ -117,7 +117,12 @@
         Public method to return the current frame.
         
         @return the current frame
+        @rtype frame object
         """
+        # Don't show any local frames after the program was stopped
+        if self.quitting:
+            return None
+        
         return self.currentFrame
     
     def getFrameLocals(self, frmnr=0):
--- a/DebugClients/Python/ThreadExtension.py	Sat Oct 08 21:01:32 2016 +0200
+++ b/DebugClients/Python/ThreadExtension.py	Sun Oct 09 22:22:36 2016 +0200
@@ -145,6 +145,7 @@
         Public method to set the current thread.
 
         @param id the id the current thread should be set to.
+        @type int
         """
         try:
             self.lockClient()
@@ -159,6 +160,7 @@
         """
         Public method to send the list of threads.
         """
+        self.updateThreadList()
         threadList = []
         if len(self.threads) > 1:
             currentId = _thread.get_ident()
@@ -187,6 +189,54 @@
             "threadList": threadList,
         })
     
+    def getExecutedFrame(self, frame):
+        """
+        Public method to return the currently executed frame.
+        
+        @param frame the current frame
+        @type frame object
+        @return the frame which is excecuted (without debugger frames)
+        @rtype frame object
+        """
+        # to get the currently executed frame, skip all frames belonging to the
+        # debugger
+        while frame is not None:
+            baseName = os.path.basename(frame.f_code.co_filename)
+            if not baseName.startswith(
+                    ('DebugClientBase.py', 'DebugBase.py', 'AsyncIO.py',
+                     'ThreadExtension.py', 'threading.py')):
+                break
+            frame = frame.f_back
+        
+        return frame
+    
+    def updateThreadList(self):
+        """
+        Public method to update the list of running threads.
+        """
+        frames = sys._current_frames()
+        for id, frame in frames.items():
+            # skip our own timer thread
+            if frame.f_code.co_name == '__eventPollTimer':
+                continue
+            
+            # Unknown thread
+            if id not in self.threads:
+                newThread = DebugBase(self)
+                name = 'Thread-{0}'.format(self.threadNumber)
+                self.threadNumber += 1
+                
+                newThread.id = id
+                newThread.name = name
+                self.threads[id] = newThread
+            
+            # adjust current frame
+            self.threads[id].currentFrame = self.getExecutedFrame(frame)
+        
+        # Clean up obsolet because terminated threads
+        self.threads = {id_: thrd for id_, thrd in self.threads.items()
+                        if id_ in frames}
+    
     def find_module(self, fullname, path=None):
         """
         Public method returning the module loader.

eric ide

mercurial