def getInternalQueue(self, thread_id): """ returns intenal command queue for a given thread. if new queue is created, notify the RDB about it """ try: return self.cmdQueue[thread_id] except KeyError: self.internalQueueLock.acquire() try: self.cmdQueue[thread_id] = PydevQueue.Queue() all_threads = threading.enumerate() cmd = None for t in all_threads: if GetThreadId(t) == thread_id: if not hasattr(t, 'additionalInfo'): #see http://sourceforge.net/tracker/index.php?func=detail&aid=1955428&group_id=85796&atid=577329 #Let's create the additional info right away! t.additionalInfo = PyDBAdditionalThreadInfo() self.RUNNING_THREAD_IDS[thread_id] = t cmd = self.cmdFactory.makeThreadCreatedMessage(t) break if cmd: PydevdLog(2, "found a new thread ", str(thread_id)) self.writer.addCommand(cmd) else: PydevdLog(0, "could not find thread by id to register") finally: self.internalQueueLock.release() return self.cmdQueue[thread_id]
def trace_dispatch(self, frame, event, arg): ''' This is the callback used when we enter some context in the debugger. We also decorate the thread we are in with info about the debugging. The attributes added are: pydev_state pydev_step_stop pydev_step_cmd pydev_notify_kill ''' try: if self._finishDebuggingSession: #that was not working very well because jython gave some socket errors threads = threadingEnumerate() for t in threads: if hasattr(t, 'doKill'): t.doKill() return None filename, base = GetFilenameAndBase(frame) is_file_to_ignore = DictContains( DONT_TRACE, base ) #we don't want to debug threading or anything related to pydevd if not self.force_post_mortem_stop: #If we're in post mortem mode, we might not have another chance to show that info! if is_file_to_ignore: return None #print('trace_dispatch', base, frame.f_lineno, event, frame.f_code.co_name) try: #this shouldn't give an exception, but it could happen... (python bug) #see http://mail.python.org/pipermail/python-bugs-list/2007-June/038796.html #and related bug: http://bugs.python.org/issue1733757 t = threadingCurrentThread() except: frame.f_trace = self.trace_dispatch return self.trace_dispatch try: additionalInfo = t.additionalInfo except: additionalInfo = t.additionalInfo = PyDBAdditionalThreadInfo() if self.force_post_mortem_stop: #If we're in post mortem mode, we might not have another chance to show that info! if additionalInfo.pydev_force_stop_at_exception: self.force_post_mortem_stop -= 1 frame, frames_byid = additionalInfo.pydev_force_stop_at_exception thread_id = GetThreadId(t) used_id = pydevd_vars.addAdditionalFrameById( thread_id, frames_byid) try: self.setSuspend(t, CMD_STEP_INTO) self.doWaitSuspend(t, frame, 'exception', None) finally: additionalInfo.pydev_force_stop_at_exception = None pydevd_vars.removeAdditionalFrameById(thread_id) # if thread is not alive, cancel trace_dispatch processing if not t.isAlive(): self.processThreadNotAlive(GetThreadId(t)) return None # suspend tracing if is_file_to_ignore: return None #each new frame... return additionalInfo.CreateDbFrame(self, filename, additionalInfo, t, frame).trace_dispatch( frame, event, arg) except SystemExit: return None except Exception: #Log it if traceback is not None: #This can actually happen during the interpreter shutdown in Python 2.7 traceback.print_exc() return None
def _locked_settrace(host, stdoutToServer, stderrToServer, port, suspend, trace_only_current_thread): if host is None: import pydev_localhost host = pydev_localhost.get_localhost() global connected global bufferStdOutToServer global bufferStdErrToServer if not connected: connected = True bufferStdOutToServer = stdoutToServer bufferStdErrToServer = stderrToServer pydevd_vm_type.SetupType() debugger = PyDB() debugger.connect(host, port) net = NetCommand(str(CMD_THREAD_CREATE), 0, '<xml><thread name="pydevd.reader" id="-1"/></xml>') debugger.writer.addCommand(net) net = NetCommand(str(CMD_THREAD_CREATE), 0, '<xml><thread name="pydevd.writer" id="-1"/></xml>') debugger.writer.addCommand(net) if bufferStdOutToServer: sys.stdoutBuf = pydevd_io.IOBuf() sys.stdout = pydevd_io.IORedirector( sys.stdout, sys.stdoutBuf) #@UndefinedVariable if bufferStdErrToServer: sys.stderrBuf = pydevd_io.IOBuf() sys.stderr = pydevd_io.IORedirector( sys.stderr, sys.stderrBuf) #@UndefinedVariable SetTraceForParents(GetFrame(), debugger.trace_dispatch) t = threadingCurrentThread() try: additionalInfo = t.additionalInfo except AttributeError: additionalInfo = PyDBAdditionalThreadInfo() t.additionalInfo = additionalInfo while not debugger.readyToRun: time.sleep(0.1) # busy wait until we receive run command if suspend: debugger.setSuspend(t, CMD_SET_BREAK) #note that we do that through pydevd_tracing.SetTrace so that the tracing #is not warned to the user! pydevd_tracing.SetTrace(debugger.trace_dispatch) if not trace_only_current_thread: #Trace future threads? try: #not available in jython! threading.settrace( debugger.trace_dispatch) # for all future threads except: pass try: thread.start_new_thread = pydev_start_new_thread thread.start_new = pydev_start_new_thread except: pass PyDBCommandThread(debugger).start() else: #ok, we're already in debug mode, with all set, so, let's just set the break debugger = GetGlobalDebugger() SetTraceForParents(GetFrame(), debugger.trace_dispatch) t = threadingCurrentThread() try: additionalInfo = t.additionalInfo except AttributeError: additionalInfo = PyDBAdditionalThreadInfo() t.additionalInfo = additionalInfo pydevd_tracing.SetTrace(debugger.trace_dispatch) if not trace_only_current_thread: #Trace future threads? try: #not available in jython! threading.settrace( debugger.trace_dispatch) # for all future threads except: pass try: thread.start_new_thread = pydev_start_new_thread thread.start_new = pydev_start_new_thread except: pass if suspend: debugger.setSuspend(t, CMD_SET_BREAK)
def settrace(host='localhost', stdoutToServer=False, stderrToServer=False, port=5678, suspend=True, trace_only_current_thread=True): '''Sets the tracing function with the pydev debug function and initializes needed facilities. @param host: the user may specify another host, if the debug server is not in the same machine @param stdoutToServer: when this is true, the stdout is passed to the debug server @param stderrToServer: when this is true, the stderr is passed to the debug server so that they are printed in its console and not in this process console. @param port: specifies which port to use for communicating with the server (note that the server must be started in the same port). @note: currently it's hard-coded at 5678 in the client @param suspend: whether a breakpoint should be emulated as soon as this function is called. @param trace_only_current_thread: determines if only the current thread will be traced or all future threads will also have the tracing enabled. ''' global connected global bufferStdOutToServer global bufferStdErrToServer if not connected: connected = True bufferStdOutToServer = stdoutToServer bufferStdErrToServer = stderrToServer pydevd_vm_type.SetupType() debugger = PyDB() debugger.connect(host, port) net = NetCommand(str(CMD_THREAD_CREATE), 0, '<xml><thread name="pydevd.reader" id="-1"/></xml>') debugger.writer.addCommand(net) net = NetCommand(str(CMD_THREAD_CREATE), 0, '<xml><thread name="pydevd.writer" id="-1"/></xml>') debugger.writer.addCommand(net) if bufferStdOutToServer: sys.stdoutBuf = pydevd_io.IOBuf() sys.stdout = pydevd_io.IORedirector( sys.stdout, sys.stdoutBuf) #@UndefinedVariable if bufferStdErrToServer: sys.stderrBuf = pydevd_io.IOBuf() sys.stderr = pydevd_io.IORedirector( sys.stderr, sys.stderrBuf) #@UndefinedVariable SetTraceForParents(GetFrame(), debugger.trace_dispatch) t = threadingCurrentThread() try: additionalInfo = t.additionalInfo except AttributeError: additionalInfo = PyDBAdditionalThreadInfo() t.additionalInfo = additionalInfo while not debugger.readyToRun: time.sleep(0.1) # busy wait until we receive run command if suspend: debugger.setSuspend(t, CMD_SET_BREAK) #note that we do that through pydevd_tracing.SetTrace so that the tracing #is not warned to the user! pydevd_tracing.SetTrace(debugger.trace_dispatch) if not trace_only_current_thread: #Trace future threads? try: #not available in jython! threading.settrace( debugger.trace_dispatch) # for all future threads except: pass try: thread.start_new_thread = pydev_start_new_thread thread.start_new = pydev_start_new_thread except: pass PyDBCommandThread(debugger).start() else: #ok, we're already in debug mode, with all set, so, let's just set the break debugger = GetGlobalDebugger() SetTraceForParents(GetFrame(), debugger.trace_dispatch) t = threadingCurrentThread() try: additionalInfo = t.additionalInfo except AttributeError: additionalInfo = PyDBAdditionalThreadInfo() t.additionalInfo = additionalInfo pydevd_tracing.SetTrace(debugger.trace_dispatch) if not trace_only_current_thread: #Trace future threads? try: #not available in jython! threading.settrace( debugger.trace_dispatch) # for all future threads except: pass try: thread.start_new_thread = pydev_start_new_thread thread.start_new = pydev_start_new_thread except: pass if suspend: debugger.setSuspend(t, CMD_SET_BREAK)