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)