def updateThreadList(self):
        """Updates the list of running threads"""
        frames = sys._current_frames()
        for threadId, frame in frames.items():
            # skip our own timer thread
            if frame.f_code.co_name == '__eventPollTimer':
                continue

            # Unknown thread
            if threadId not in self.threads:
                newThread = DebugBase(self)
                name = 'Thread-{0}'.format(self.threadNumber)
                self.threadNumber += 1

                newThread.id = threadId
                newThread.name = name
                self.threads[threadId] = newThread

            # adjust current frame
            if "__pypy__" not in sys.builtin_module_names:
                # Don't update with None
                currentFrame = self.getExecutedFrame(frame)
                if (currentFrame is not None and
                        self.threads[threadId].isBroken is False):
                    self.threads[threadId].currentFrame = currentFrame

        # Clean up obsolet because terminated threads
        self.threads = {id_: thrd for id_, thrd in self.threads.items()
                        if id_ in frames}
    def attachThread(self, target=None, args=None, kwargs=None,
                     mainThread=False):
        """
        Public method to setup a standard thread for DebugClient to debug.

        If mainThread is True, then we are attaching to the already
        started mainthread of the app and the rest of the args are ignored.
        """
        if kwargs is None:
            kwargs = {}

        if mainThread:
            ident = _thread.get_ident()
            name = 'MainThread'
            newThread = self.mainThread
            newThread.isMainThread = True
        else:
            newThread = DebugBase(self)
            ident = self._original_start_new_thread(
                newThread.bootstrap, (target, args, kwargs))
            name = 'Thread-{0}'.format(self.threadNumber)
            self.threadNumber += 1

        newThread.id = ident
        newThread.name = name

        self.threads[ident] = newThread

        return ident
    def __init__( self, dbgClient, targ = None, args = None, kwargs = None,
                  mainThread = 0 ):
        """
        Constructor

        @param dbgClient the owning client
        @param targ the target method in the run thread
        @param args  arguments to be passed to the thread
        @param kwargs arguments to be passed to the thread
        @param mainThread 0 if this thread is not the mainscripts thread
        """
        DebugBase.__init__( self, dbgClient )

        self._target = targ
        self._args = args
        self._kwargs = kwargs
        self._mainThread = mainThread

        # thread running tracks execution state of client code
        # it will always be 0 for main thread as that is tracked
        # by DebugClientThreads and Bdb...
        self._threadRunning = 0

        self.__ident = None     # id of this thread
        self.__name = ""
        return
    def trace_dispatch( self, frame, event, arg ):
        """
        Private method wrapping the trace_dispatch of bdb.py.

        It wraps the call to dispatch tracing into
        bdb to make sure we have locked the client to prevent multiple
        threads from entering the client event loop.

        @param frame The current stack frame.
        @param event The trace event (string)
        @param arg The arguments
        @return local trace function
        """
        try:
            self._dbgClient.lockClient()
            # if this thread came out of a lock, and we are quitting
            # and we are still running, then get rid of
            # tracing for this thread
            if self.quitting and self._threadRunning:
                sys.settrace( None )
                sys.setprofile( None )
            import threading
            self.__name = threading.currentThread().getName()
            retval = DebugBase.trace_dispatch( self, frame, event, arg )
        finally:
            self._dbgClient.unlockClient()

        return retval
            def _bootstrap(self, run):
                """
                Bootstrap for threading, which reports exceptions correctly.

                @param run the run method of threading.Thread
                @type method pointer
                """
                newThread = DebugBase(_debugClient)
                _debugClient.threads[self.ident] = newThread
                newThread.name = self.name
                # see DebugBase.bootstrap
                sys.settrace(newThread.trace_dispatch)
                try:
                    run()
                except Exception:
                    excinfo = sys.exc_info()
                    newThread.user_exception(excinfo, True)
                finally:
                    sys.settrace(None)
            def _bootstrapQThread(self, run):
                """Bootstrap for QThread, which reports exceptions correctly"""
                global _qtThreadNumber

                newThread = DebugBase(_debugClient)
                ident = _thread.get_ident()
                name = 'QtThread-{0}'.format(_qtThreadNumber)

                _qtThreadNumber += 1

                newThread.id = ident
                newThread.name = name

                _debugClient.threads[ident] = newThread

                # see DebugBase.bootstrap
                sys.settrace(newThread.trace_dispatch)
                try:
                    run()
                except SystemExit:
                    # *.QThreads doesn't like SystemExit
                    pass
                except Exception:
                    excinfo = sys.exc_info()
                    newThread.user_exception(excinfo, True)
                finally:
                    sys.settrace(None)
 def __init__(self):
     DebugClientBase.__init__(self)
     DebugBase.__init__(self, self)
     ThreadExtension.__init__(self)