def wait_for_connection(daemon, host, port): debugger = get_global_debugger() while debugger is None: time.sleep(0.1) debugger = get_global_debugger() debugger.ready_to_run = True server = create_server(host, port) client, _ = server.accept() daemon.set_connection(client) daemon.re_build_breakpoints() on_attach()
def _pydev_stop_at_break(line): frame = sys._getframe(1) t = threading.current_thread() if t.additional_info.is_tracing: return False t.additional_info.is_tracing = True try: debugger = get_global_debugger() try: abs_path_real_path_and_base = NORM_PATHS_AND_BASE_CONTAINER[ frame.f_code.co_filename] except: abs_path_real_path_and_base = get_abs_path_real_path_and_base_from_frame( frame) filename = abs_path_real_path_and_base[1] breakpoints_for_file = debugger.breakpoints.get(filename) try: python_breakpoint = breakpoints_for_file[line] except KeyError: pydev_log.debug( "Couldn't find breakpoint in the file {} on line {}".format( frame.f_code.co_filename, line)) return if python_breakpoint: pydev_log.debug( "Suspending at breakpoint in file: {} on line {}".format( frame.f_code.co_filename, line)) t.additional_info.trace_suspend_type = 'frame_eval' pydevd_frame_eval_cython_wrapper = sys.modules[ '_pydevd_frame_eval.pydevd_frame_eval_cython_wrapper'] thread_info = pydevd_frame_eval_cython_wrapper.get_thread_info_py() if thread_info.thread_trace_func is not None: frame.f_trace = thread_info.thread_trace_func else: debugger = get_global_debugger() frame.f_trace = debugger.get_thread_local_trace_func() # For bytecode patching issue diagnosis. Can make the debugger really slow. if os.environ.get( 'PYDEVD_TRACE_OPCODES') == 'True' and IS_PY37_OR_GREATER: frame.f_trace_opcodes = True finally: t.additional_info.is_tracing = False
def wait_for_connection(daemon, host, port, next_session=None): debugger = get_global_debugger() while debugger is None: time.sleep(0.1) debugger = get_global_debugger() debugger.ready_to_run = True while True: session_not_bound.wait() try: global_next_session() on_attach() except DaemonClosedError: return
def new_fork(): import os # A simple fork will result in a new python process is_new_python_process = True frame = sys._getframe() while frame is not None: if frame.f_code.co_name == '_execute_child' and 'subprocess' in frame.f_code.co_filename: # If we're actually in subprocess.Popen creating a child, it may # result in something which is not a Python process, (so, we # don't want to connect with it in the forked version). executable = frame.f_locals.get('executable') if executable is not None: is_new_python_process = False if is_python(executable): is_new_python_process = True break frame = frame.f_back frame = None # Just make sure we don't hold on to it. child_process = getattr(os, original_name)() # fork if not child_process: if is_new_python_process: _on_forked_process() else: if is_new_python_process: from _pydevd_bundle.pydevd_comm import get_global_debugger debugger = get_global_debugger() if debugger is not None: debugger.send_process_created_message() return child_process
def _excepthook(exctype, value, tb): from _pydevd_bundle.pydevd_frame import handle_breakpoint_condition, handle_breakpoint_expression global _handle_exceptions if _handle_exceptions: exception_breakpoint = get_exception_breakpoint(exctype, _handle_exceptions) else: exception_breakpoint = None #Always call the original excepthook before going on to call the debugger post mortem to show it. _original_excepthook(exctype, value, tb) if not exception_breakpoint: return if tb is None: #sometimes it can be None, e.g. with GTK return if exctype is KeyboardInterrupt: return frames = [] debugger = get_global_debugger() user_frame = None while tb: frame = tb.tb_frame if exception_breakpoint.ignore_libraries and not debugger.not_in_scope(frame.f_code.co_filename): user_frame = tb.tb_frame frames.append(tb.tb_frame) tb = tb.tb_next thread = threadingCurrentThread() frames_byid = dict([(id(frame),frame) for frame in frames]) if exception_breakpoint.ignore_libraries and user_frame is not None: frame = user_frame else: frame = frames[-1] exception = (exctype, value, tb) _set_additional_info_if_needed(thread) info = thread.additional_info add_exception_to_frame(frame, exception) if exception_breakpoint.condition is not None: eval_result = handle_breakpoint_condition(debugger, info, exception_breakpoint, frame) if not eval_result: return if exception_breakpoint.expression is not None: handle_breakpoint_expression(exception_breakpoint, info, frame) try: thread.additional_info.pydev_message = exception_breakpoint.qname except: thread.additional_info.pydev_message = exception_breakpoint.qname.encode('utf-8') pydevd_tracing.SetTrace(None) #no tracing from here pydev_log.debug('Handling post-mortem stop on exception breakpoint %s' % exception_breakpoint.qname) debugger.handle_post_mortem_stop(thread, frame, frames_byid, exception)
def set_trace_in_qt(): from _pydevd_bundle import pydevd_tracing from _pydevd_bundle.pydevd_comm import get_global_debugger debugger = get_global_debugger() if debugger is not None: pydevd_tracing.SetTrace(debugger.trace_dispatch, debugger.frame_eval_func)
def _pydev_needs_stop_at_break(line): ''' We separate the functionality into 2 functions so that we can generate a bytecode which generates a spurious line change so that we can do: if _pydev_needs_stop_at_break(): # Set line to line -1 _pydev_stop_at_break() # then, proceed to go to the current line # (which will then trigger a line event). ''' t = threading.currentThread() try: additional_info = t.additional_info except: additional_info = set_additional_thread_info(t) if additional_info.is_tracing: return False additional_info.is_tracing += 1 try: frame = sys._getframe(1) # print('pydev needs stop at break?', line, 'curr line', frame.f_lineno, 'curr trace', frame.f_trace) if frame.f_trace is not None: # i.e.: this frame is already being traced, thus, we don't need to use programmatic breakpoints. return False py_db = get_global_debugger() if py_db is None: return False try: abs_path_real_path_and_base = NORM_PATHS_AND_BASE_CONTAINER[ frame.f_code.co_filename] except: abs_path_real_path_and_base = get_abs_path_real_path_and_base_from_frame( frame) canonical_normalized_filename = abs_path_real_path_and_base[1] try: python_breakpoint = py_db.breakpoints[ canonical_normalized_filename][line] except: # print("Couldn't find breakpoint in the file %s on line %s" % (frame.f_code.co_filename, line)) # Could be KeyError if line is not there or TypeError if breakpoints_for_file is None. # Note: using catch-all exception for performance reasons (if the user adds a breakpoint # and then removes it after hitting it once, this method added for the programmatic # breakpoint will keep on being called and one of those exceptions will always be raised # here). return False if python_breakpoint: # print('YES') return True finally: additional_info.is_tracing -= 1 return False
def run(*args, **kwargs): debugger = get_global_debugger() if debugger is not None: SetTrace(debugger.trace_dispatch) debugger = None return _original_run(*args, **kwargs)
def _schedule_callback(prev, next): ''' Called when a context is stopped or a new context is made runnable. ''' try: if not prev and not next: return if next: register_tasklet_info(next) # Ok, making next runnable: set the tracing facility in it. debugger = get_global_debugger() if debugger is not None and next.frame: if hasattr(next.frame, 'f_trace'): next.frame.f_trace = debugger.trace_dispatch debugger = None if prev: register_tasklet_info(prev) try: for tasklet_ref, tasklet_info in dict_items(_weak_tasklet_registered_to_info): # Make sure it's a copy! tasklet = tasklet_ref() if tasklet is None or not tasklet.alive: # Garbage-collected already! try: del _weak_tasklet_registered_to_info[tasklet_ref] except KeyError: pass if tasklet_info.frame_id is not None: remove_custom_frame(tasklet_info.frame_id) else: if tasklet.paused or tasklet.blocked or tasklet.scheduled: if tasklet.frame and tasklet.frame.f_back: f_back = tasklet.frame.f_back base = get_abs_path_real_path_and_base_from_frame(f_back)[-1] is_file_to_ignore = dict_contains(DONT_TRACE, base) if not is_file_to_ignore: if tasklet_info.frame_id is None: tasklet_info.frame_id = add_custom_frame(f_back, tasklet_info.tasklet_name, tasklet.thread_id) else: update_custom_frame(tasklet_info.frame_id, f_back, tasklet.thread_id) elif tasklet.is_current: if tasklet_info.frame_id is not None: # Remove info about stackless suspended when it starts to run. remove_custom_frame(tasklet_info.frame_id) tasklet_info.frame_id = None finally: tasklet = None tasklet_info = None f_back = None except: import traceback;traceback.print_exc() if _application_set_schedule_callback is not None: return _application_set_schedule_callback(prev, next)
def _pydev_stop_at_break(): frame = sys._getframe(1) t = threading.currentThread() if t.additional_info.is_tracing: return False if t.additional_info.pydev_step_cmd == -1 and frame.f_trace in (None, dummy_tracing_holder.dummy_trace_func): # do not handle breakpoints while stepping, because they're handled by old tracing function t.additional_info.is_tracing = True debugger = get_global_debugger() try: abs_path_real_path_and_base = NORM_PATHS_AND_BASE_CONTAINER[frame.f_code.co_filename] except: abs_path_real_path_and_base = get_abs_path_real_path_and_base_from_frame(frame) filename = abs_path_real_path_and_base[1] breakpoints_for_file = debugger.breakpoints.get(filename) line = _get_line_for_frame(frame) try: breakpoint = breakpoints_for_file[line] except KeyError: pydev_log.debug("Couldn't find breakpoint in the file {} on line {}".format(frame.f_code.co_filename, line)) t.additional_info.is_tracing = False return False if breakpoint and handle_breakpoint(frame, t, debugger, breakpoint): pydev_log.debug("Suspending at breakpoint in file: {} on line {}".format(frame.f_code.co_filename, line)) debugger.set_suspend(t, CMD_SET_BREAK) debugger.do_wait_suspend(t, frame, 'line', None, "frame_eval") t.additional_info.is_tracing = False return t.additional_info.pydev_step_cmd == CMD_SET_NEXT_STATEMENT return False
def _pydev_stop_at_break(line): frame = sys._getframe(1) # print('pydevd SET TRACING at ', line, 'curr line', frame.f_lineno) t = threading.current_thread() try: additional_info = t.additional_info except: additional_info = set_additional_thread_info(t) if additional_info.is_tracing: return additional_info.is_tracing += 1 try: py_db = get_global_debugger() if py_db is None: return pydev_log.debug("Setting f_trace due to frame eval mode in file: %s on line %s", frame.f_code.co_filename, line) additional_info.trace_suspend_type = 'frame_eval' pydevd_frame_eval_cython_wrapper = sys.modules['_pydevd_frame_eval.pydevd_frame_eval_cython_wrapper'] thread_info = pydevd_frame_eval_cython_wrapper.get_thread_info_py() if thread_info.thread_trace_func is not None: frame.f_trace = thread_info.thread_trace_func else: frame.f_trace = py_db.get_thread_local_trace_func() finally: additional_info.is_tracing -= 1
def enable_attach(address=(DEFAULT_HOST, DEFAULT_PORT), redirect_output=True): """Enables a client to attach to this process remotely to debug Python code. Parameters ---------- address : (str, int), optional Specifies the interface and port on which the debugging server should listen for TCP connections. It is in the same format as used for regular sockets of the `socket.AF_INET` family, i.e. a tuple of ``(hostname, port)``. On client side, the server is identified by the Qualifier string in the usual ``'hostname:port'`` format, e.g.: ``'myhost.cloudapp.net:5678'``. Default is ``('0.0.0.0', 5678)``. redirect_output : bool, optional Specifies whether any output (on both `stdout` and `stderr`) produced by this program should be sent to the debugger. Default is ``True``. Notes ----- This function returns immediately after setting up the debugging server, and does not block program execution. If you need to block until debugger is attached, call `ptvsd.wait_for_attach`. The debugger can be detached and re-attached multiple times after `enable_attach` is called. Only the thread on which this function is called, and any threads that are created after it returns, will be visible in the debugger once it is attached. Any threads that are already running before this function is called will not be visible. """ if get_global_debugger() is not None: return _attached.clear() ptvsd_enable_attach(address, redirect_output, on_attach=_attached.set)
def run(*args, **kwargs): debugger = get_global_debugger() if debugger is not None: debugger.enable_tracing() debugger = None return _original_run(*args, **kwargs)
def _schedule_callback(prev, next): ''' Called when a context is stopped or a new context is made runnable. ''' try: if not prev and not next: return if next: register_tasklet_info(next) # Ok, making next runnable: set the tracing facility in it. debugger = get_global_debugger() if debugger is not None and next.frame: if hasattr(next.frame, 'f_trace'): next.frame.f_trace = debugger.trace_dispatch debugger = None if prev: register_tasklet_info(prev) try: for tasklet_ref, tasklet_info in dict_items(_weak_tasklet_registered_to_info): # Make sure it's a copy! tasklet = tasklet_ref() if tasklet is None or not tasklet.alive: # Garbage-collected already! try: del _weak_tasklet_registered_to_info[tasklet_ref] except KeyError: pass if tasklet_info.frame_id is not None: remove_custom_frame(tasklet_info.frame_id) else: if tasklet.paused or tasklet.blocked or tasklet.scheduled: if tasklet.frame and tasklet.frame.f_back: f_back = tasklet.frame.f_back base = get_abs_path_real_path_and_base_from_frame(f_back)[-1] is_file_to_ignore = base in DONT_TRACE if not is_file_to_ignore: if tasklet_info.frame_id is None: tasklet_info.frame_id = add_custom_frame(f_back, tasklet_info.tasklet_name, tasklet.thread_id) else: update_custom_frame(tasklet_info.frame_id, f_back, tasklet.thread_id) elif tasklet.is_current: if tasklet_info.frame_id is not None: # Remove info about stackless suspended when it starts to run. remove_custom_frame(tasklet_info.frame_id) tasklet_info.frame_id = None finally: tasklet = None tasklet_info = None f_back = None except: import traceback;traceback.print_exc() if _application_set_schedule_callback is not None: return _application_set_schedule_callback(prev, next)
def wait_for_connection(daemon, host, port, next_session=None): ptvsd.log.debug('Waiting for pydevd ...') debugger = get_global_debugger() while debugger is None: time.sleep(0.1) debugger = get_global_debugger() ptvsd.log.debug('Unblocking pydevd.') debugger.ready_to_run = True while True: session_not_bound.wait() try: global_next_session() on_attach() except DaemonClosedError: return
def _pydev_stop_at_break(line): frame = sys._getframe(1) t = threading.currentThread() if t.additional_info.is_tracing: return False t.additional_info.is_tracing = True try: debugger = get_global_debugger() try: abs_path_real_path_and_base = NORM_PATHS_AND_BASE_CONTAINER[ frame.f_code.co_filename] except: abs_path_real_path_and_base = get_abs_path_real_path_and_base_from_frame( frame) filename = abs_path_real_path_and_base[1] try: python_breakpoint = debugger.breakpoints[filename][line] except: # print("Couldn't find breakpoint in the file %s on line %s" % (frame.f_code.co_filename, line)) # Could be KeyError if line is not there or TypeError if breakpoints_for_file is None. # Note: using catch-all exception for performance reasons (if the user adds a breakpoint # and then removes it after hitting it once, this method added for the programmatic # breakpoint will keep on being called and one of those exceptions will always be raised # here). return if python_breakpoint: pydev_log.debug( "Suspending at breakpoint in file: {} on line {}".format( frame.f_code.co_filename, line)) t.additional_info.trace_suspend_type = 'frame_eval' pydevd_frame_eval_cython_wrapper = sys.modules[ '_pydevd_frame_eval.pydevd_frame_eval_cython_wrapper'] thread_info = pydevd_frame_eval_cython_wrapper.get_thread_info_py() if thread_info.thread_trace_func is not None: frame.f_trace = thread_info.thread_trace_func else: debugger = get_global_debugger() frame.f_trace = debugger.get_thread_local_trace_func() finally: t.additional_info.is_tracing = False
def _pydev_stop_at_break(line): frame = sys._getframe(1) t = threading.currentThread() if t.additional_info.is_tracing: return False t.additional_info.is_tracing = True try: debugger = get_global_debugger() try: abs_path_real_path_and_base = NORM_PATHS_AND_BASE_CONTAINER[ frame.f_code.co_filename] except: abs_path_real_path_and_base = get_abs_path_real_path_and_base_from_frame( frame) filename = abs_path_real_path_and_base[1] breakpoints_for_file = debugger.breakpoints.get(filename) try: python_breakpoint = breakpoints_for_file[line] except KeyError: pydev_log.debug( "Couldn't find breakpoint in the file {} on line {}".format( frame.f_code.co_filename, line)) return if python_breakpoint: pydev_log.debug( "Suspending at breakpoint in file: {} on line {}".format( frame.f_code.co_filename, line)) t.additional_info.trace_suspend_type = 'frame_eval' pydevd_frame_eval_cython_wrapper = sys.modules[ '_pydevd_frame_eval.pydevd_frame_eval_cython_wrapper'] thread_info = pydevd_frame_eval_cython_wrapper.get_thread_info_py() if thread_info.thread_trace_func is not None: frame.f_trace = thread_info.thread_trace_func else: debugger = get_global_debugger() frame.f_trace = debugger.get_thread_local_trace_func() finally: t.additional_info.is_tracing = False
def send_process_will_be_substituted(): """Sends a message that a new process is going to be created. When `PyDB` works in server mode this method also waits for the response from IDE to be sure that IDE received this message. """ from _pydevd_bundle.pydevd_comm import get_global_debugger debugger = get_global_debugger() if debugger is not None: debugger.send_process_will_be_substituted()
def notify_root(port): assert options.subprocess_of debug('Subprocess %d notifying root process at port %d' % (os.getpid(), options.subprocess_notify)) conn = create_client() conn.connect(('localhost', options.subprocess_notify)) stream = JsonIOStream.from_socket(conn) channel = JsonMessageChannel(stream) channel.start() # Send the notification about ourselves to root, and wait for it to tell us # whether an incoming connection is anticipated. This will be true if root # had successfully propagated the notification to the IDE, and false if it # couldn't do so (e.g. because the IDE is not attached). There's also the # possibility that connection to root will just drop, e.g. if it crashes - # in that case, just exit immediately. request = channel.send_request( 'ptvsd_subprocess', { 'parentProcessId': options.subprocess_of, 'processId': os.getpid(), 'port': port, }) try: response = request.wait_for_response() except Exception: print('Failed to send subprocess notification; exiting', file=sys.__stderr__) traceback.print_exc() sys.exit(0) # Keep the channel open until we exit - root process uses open channels to keep # track of which subprocesses are alive and which are not. atexit.register(lambda: channel.close()) if not response['incomingConnection']: debugger = get_global_debugger() while debugger is None: time.sleep(0.1) debugger = get_global_debugger() debugger.ready_to_run = True
def __set__(self, obj, value): global_debugger = get_global_debugger() try: if global_debugger is not None and global_debugger.disable_property_setter_trace: global_debugger.disable_tracing() if self.fset is None: raise AttributeError("can't set attribute") self.fset(obj, value) finally: if global_debugger is not None: global_debugger.enable_tracing()
def __delete__(self, obj): global_debugger = get_global_debugger() try: if global_debugger is not None and global_debugger.disable_property_deleter_trace: global_debugger.disable_tracing() if self.fdel is None: raise AttributeError("can't delete attribute") self.fdel(obj) finally: if global_debugger is not None: global_debugger.enable_tracing()
def __delete__(self, obj): global_debugger = get_global_debugger() try: if global_debugger is not None and global_debugger.disable_property_deleter_trace: pydevd_tracing.SetTrace(None) if self.fdel is None: raise AttributeError("can't delete attribute") self.fdel(obj) finally: if global_debugger is not None: pydevd_tracing.SetTrace(global_debugger.trace_dispatch)
def __set__(self, obj, value): global_debugger = get_global_debugger() try: if global_debugger is not None and global_debugger.disable_property_setter_trace: pydevd_tracing.SetTrace(None) if self.fset is None: raise AttributeError("can't set attribute") self.fset(obj, value) finally: if global_debugger is not None: pydevd_tracing.SetTrace(global_debugger.trace_dispatch)
def _pydev_stop_at_break(line): frame = sys._getframe(1) t = threading.currentThread() if t.additional_info.is_tracing: return False t.additional_info.is_tracing = True try: debugger = get_global_debugger() try: abs_path_real_path_and_base = NORM_PATHS_AND_BASE_CONTAINER[frame.f_code.co_filename] except: abs_path_real_path_and_base = get_abs_path_real_path_and_base_from_frame(frame) filename = abs_path_real_path_and_base[1] try: python_breakpoint = debugger.breakpoints[filename][line] except: # print("Couldn't find breakpoint in the file %s on line %s" % (frame.f_code.co_filename, line)) # Could be KeyError if line is not there or TypeError if breakpoints_for_file is None. # Note: using catch-all exception for performance reasons (if the user adds a breakpoint # and then removes it after hitting it once, this method added for the programmatic # breakpoint will keep on being called and one of those exceptions will always be raised # here). return if python_breakpoint: pydev_log.debug("Suspending at breakpoint in file: {} on line {}".format(frame.f_code.co_filename, line)) t.additional_info.trace_suspend_type = 'frame_eval' pydevd_frame_eval_cython_wrapper = sys.modules['_pydevd_frame_eval.pydevd_frame_eval_cython_wrapper'] thread_info = pydevd_frame_eval_cython_wrapper.get_thread_info_py() if thread_info.thread_trace_func is not None: frame.f_trace = thread_info.thread_trace_func else: debugger = get_global_debugger() frame.f_trace = debugger.get_thread_local_trace_func() finally: t.additional_info.is_tracing = False
def notify_root(port): assert options.subprocess_of debug('Subprocess %d notifying root process at port %d' % (os.getpid(), options.subprocess_notify)) conn = create_client() conn.connect(('localhost', options.subprocess_notify)) stream = JsonIOStream.from_socket(conn) channel = JsonMessageChannel(stream) channel.start() # Send the notification about ourselves to root, and wait for it to tell us # whether an incoming connection is anticipated. This will be true if root # had successfully propagated the notification to the IDE, and false if it # couldn't do so (e.g. because the IDE is not attached). There's also the # possibility that connection to root will just drop, e.g. if it crashes - # in that case, just exit immediately. request = channel.send_request('ptvsd_subprocess', { 'parentProcessId': options.subprocess_of, 'processId': os.getpid(), 'port': port, }) try: response = request.wait_for_response() except Exception: print('Failed to send subprocess notification; exiting', file=sys.__stderr__) traceback.print_exc() sys.exit(0) # Keep the channel open until we exit - root process uses open channels to keep # track of which subprocesses are alive and which are not. atexit.register(lambda: channel.close()) if not response['incomingConnection']: debugger = get_global_debugger() while debugger is None: time.sleep(0.1) debugger = get_global_debugger() debugger.ready_to_run = True
def _excepthook(exctype, value, tb): global _handle_exceptions if _handle_exceptions: exception_breakpoint = get_exception_breakpoint( exctype, _handle_exceptions) else: exception_breakpoint = None #Always call the original excepthook before going on to call the debugger post mortem to show it. _original_excepthook(exctype, value, tb) if not exception_breakpoint: return if tb is None: #sometimes it can be None, e.g. with GTK return if exctype is KeyboardInterrupt: return frames = [] debugger = get_global_debugger() user_frame = None while tb: frame = tb.tb_frame if exception_breakpoint.ignore_libraries and not debugger.not_in_scope( frame.f_code.co_filename): user_frame = tb.tb_frame frames.append(tb.tb_frame) tb = tb.tb_next thread = threadingCurrentThread() frames_byid = dict([(id(frame), frame) for frame in frames]) if exception_breakpoint.ignore_libraries and user_frame is not None: frame = user_frame else: frame = frames[-1] exception = (exctype, value, tb) _set_additional_info_if_needed(thread) try: thread.additional_info.pydev_message = exception_breakpoint.qname except: thread.additional_info.pydev_message = exception_breakpoint.qname.encode( 'utf-8') pydevd_tracing.SetTrace(None) #no tracing from here pydev_log.debug('Handling post-mortem stop on exception breakpoint %s' % exception_breakpoint.qname) debugger.handle_post_mortem_stop(thread, frame, frames_byid, exception)
def wait_for_connection(daemon, host, port, next_session=None): ptvsd.log.debug('Waiting for pydevd ...') debugger = get_global_debugger() while debugger is None: time.sleep(0.1) debugger = get_global_debugger() ptvsd.log.debug('Unblocking pydevd.') debugger.ready_to_run = True while True: try: session_not_bound.wait() try: global_next_session() on_attach() except DaemonClosedError: return except TypeError: # May happen during interpreter shutdown # (if some global -- such as global_next_session becomes None). return
def __get__(self, obj, objtype=None): if obj is None: return self global_debugger = get_global_debugger() try: if global_debugger is not None and global_debugger.disable_property_getter_trace: pydevd_tracing.SetTrace(None) if self.fget is None: raise AttributeError("unreadable attribute") return self.fget(obj) finally: if global_debugger is not None: pydevd_tracing.SetTrace(global_debugger.trace_dispatch)
def __call__(self): _on_set_trace_for_new_thread() from _pydevd_bundle.pydevd_comm import get_global_debugger global_debugger = get_global_debugger() if global_debugger is not None and global_debugger.thread_analyser is not None: # we can detect start_new_thread only here try: from pydevd_concurrency_analyser.pydevd_concurrency_logger import log_new_thread log_new_thread(global_debugger) except: sys.stderr.write("Failed to detect new thread for visualization") return self.original_func(*self.args, **self.kwargs)
def new_f(old_f, args, kwargs): debugger = get_global_debugger() if debugger is not None: debugger.enable_tracing() debugger = None # Remove our own traces :) self.tempval = old_f register_tasklet_info(self) # Hover old_f to see the stackless being created and *args and **kwargs to see its parameters. return old_f(*args, **kwargs)
def __call__(self): _on_set_trace_for_new_thread() from _pydevd_bundle.pydevd_comm import get_global_debugger global_debugger = get_global_debugger() if global_debugger is not None and global_debugger.thread_analyser is not None: # we can detect start_new_thread only here try: from pydevd_concurrency_analyser.pydevd_concurrency_logger import log_new_thread log_new_thread(global_debugger) except: sys.stderr.write( "Failed to detect new thread for visualization") return self.original_func(*self.args, **self.kwargs)
def suspend_at_builtin_breakpoint(): # used by built-in breakpoint() function appeared in Python 3.7 frame = sys._getframe(3) t = threading.currentThread() if t.additional_info.is_tracing: return False if t.additional_info.pydev_step_cmd == -1: # do not handle breakpoints while stepping, because they're handled by old tracing function t.additional_info.is_tracing = True pydev_log.debug("Suspending at breakpoint in file: {} on line {}".format(frame.f_code.co_filename, frame.f_lineno)) debugger = get_global_debugger() debugger.set_suspend(t, CMD_SET_BREAK) debugger.do_wait_suspend(t, frame, 'line', None, "frame_eval") t.additional_info.is_tracing = False return t.additional_info.pydev_step_cmd == CMD_SET_NEXT_STATEMENT return False
def break_into_debugger(): """If a remote debugger is attached, pauses execution of all threads, and breaks into the debugger with current thread as active. """ debugger = get_global_debugger() if not _attached.isSet() or debugger is None: return thread = pydevd.threadingCurrentThread() try: additional_info = thread.additional_info except AttributeError: additional_info = PyDBAdditionalThreadInfo() thread.additional_info = additional_info debugger.set_suspend(thread, CMD_THREAD_SUSPEND)
def suspend_at_builtin_breakpoint(): # used by built-in breakpoint() function appeared in Python 3.7 frame = sys._getframe(3) t = threading.current_thread() if t.additional_info.is_tracing: return False if t.additional_info.pydev_step_cmd == -1: # do not handle breakpoints while stepping, because they're handled by old tracing function t.additional_info.is_tracing = True pydev_log.debug( "Suspending at breakpoint in file: {} on line {}".format( frame.f_code.co_filename, frame.f_lineno)) debugger = get_global_debugger() debugger.set_suspend(t, CMD_SET_BREAK) debugger.do_wait_suspend(t, frame, 'line', None, "frame_eval") frame.f_trace = debugger.get_thread_local_trace_func() t.additional_info.is_tracing = False
def set_project_roots(project_roots): from _pydevd_bundle.pydevd_comm import get_global_debugger if sys.version_info[0] <= 2: # In py2 we need bytes for the files. project_roots = [ root if not isinstance(root, unicode) else root.encode(sys.getfilesystemencoding()) for root in project_roots ] pydev_log.debug("IDE_PROJECT_ROOTS %s\n" % project_roots) new_roots = [] for root in project_roots: new_roots.append(os.path.normcase(root)) # Leave only the last one added. _PROJECT_ROOTS_CACHE.append(new_roots) del _PROJECT_ROOTS_CACHE[:-1] # Clear related caches. _FILENAME_TO_IN_SCOPE_CACHE.clear() debugger = get_global_debugger() if debugger is not None: debugger.clear_skip_caches()
def __call__(self): # We monkey-patch the thread creation so that this function is called in the new thread. At this point # we notify of its creation and start tracing it. from _pydevd_bundle.pydevd_constants import get_thread_id from _pydevd_bundle.pydevd_comm import get_global_debugger global_debugger = get_global_debugger() thread_id = None if global_debugger is not None: # Note: if this is a thread from threading.py, we're too early in the boostrap process (because we mocked # the start_new_thread internal machinery and thread._bootstrap has not finished), so, the code below needs # to make sure that we use the current thread bound to the original function and not use # threading.currentThread() unless we're sure it's a dummy thread. t = getattr(self.original_func, '__self__', getattr(self.original_func, 'im_self', None)) if not isinstance(t, threading.Thread): # This is not a threading.Thread but a Dummy thread (so, get it as a dummy thread using # currentThread). t = threading.currentThread() if not getattr(t, 'is_pydev_daemon_thread', False): thread_id = get_thread_id(t) global_debugger.notify_thread_created(thread_id, t) _on_set_trace_for_new_thread(global_debugger) if global_debugger.thread_analyser is not None: try: from pydevd_concurrency_analyser.pydevd_concurrency_logger import log_new_thread log_new_thread(global_debugger, t) except: sys.stderr.write( "Failed to detect new thread for visualization") try: ret = self.original_func(*self.args, **self.kwargs) finally: if thread_id is not None: global_debugger.notify_thread_not_alive(thread_id) return ret
def _on_set_trace_for_new_thread(): from _pydevd_bundle.pydevd_comm import get_global_debugger global_debugger = get_global_debugger() if global_debugger is not None: global_debugger.SetTrace(global_debugger.trace_dispatch)
def unblock_debugger(): debugger = get_global_debugger() while debugger is None: time.sleep(0.1) debugger = get_global_debugger() debugger.ready_to_run = True
def execute_tests_in_parallel(tests, jobs, split, verbosity, coverage_files, coverage_include): ''' @param tests: list(PydevTestSuite) A list with the suites to be run @param split: str Either 'module' or the number of tests that should be run in each batch @param coverage_files: list(file) A list with the files that should be used for giving coverage information (if empty, coverage information should not be gathered). @param coverage_include: str The pattern that should be included in the coverage. @return: bool Returns True if the tests were actually executed in parallel. If the tests were not executed because only 1 should be used (e.g.: 2 jobs were requested for running 1 test), False will be returned and no tests will be run. It may also return False if in debug mode (in which case, multi-processes are not accepted) ''' try: from _pydevd_bundle.pydevd_comm import get_global_debugger if get_global_debugger() is not None: return False except: pass #Ignore any error here. #This queue will receive the tests to be run. Each entry in a queue is a list with the tests to be run together When #split == 'tests', each list will have a single element, when split == 'module', each list will have all the tests #from a given module. tests_queue = [] queue_elements = [] if split == 'module': module_to_tests = {} for test in tests: lst = [] flatten_test_suite(test, lst) for test in lst: key = (test.__pydev_pyfile__, test.__pydev_module_name__) module_to_tests.setdefault(key, []).append(test) for key, tests in module_to_tests.items(): queue_elements.append(tests) if len(queue_elements) < jobs: #Don't create jobs we will never use. jobs = len(queue_elements) elif split == 'tests': for test in tests: lst = [] flatten_test_suite(test, lst) for test in lst: queue_elements.append([test]) if len(queue_elements) < jobs: #Don't create jobs we will never use. jobs = len(queue_elements) else: raise AssertionError('Do not know how to handle: %s' % (split,)) for test_cases in queue_elements: test_queue_elements = [] for test_case in test_cases: try: test_name = test_case.__class__.__name__+"."+test_case._testMethodName except AttributeError: #Support for jython 2.1 (__testMethodName is pseudo-private in the test case) test_name = test_case.__class__.__name__+"."+test_case._TestCase__testMethodName test_queue_elements.append(test_case.__pydev_pyfile__+'|'+test_name) tests_queue.append(test_queue_elements) if jobs < 2: return False sys.stdout.write('Running tests in parallel with: %s jobs.\n' %(jobs,)) queue = Queue.Queue() for item in tests_queue: queue.put(item, block=False) providers = [] clients = [] for i in range(jobs): test_cases_provider = CommunicationThread(queue) providers.append(test_cases_provider) test_cases_provider.start() port = test_cases_provider.port if coverage_files: clients.append(ClientThread(i, port, verbosity, coverage_files.pop(0), coverage_include)) else: clients.append(ClientThread(i, port, verbosity)) for client in clients: client.start() client_alive = True while client_alive: client_alive = False for client in clients: #Wait for all the clients to exit. if not client.finished: client_alive = True time.sleep(.2) break for provider in providers: provider.shutdown() return True
def get_debugger(self): from _pydevd_bundle.pydevd_comm import get_global_debugger return get_global_debugger()
def set_trace_in_qt(): import pydevd_tracing from _pydevd_bundle.pydevd_comm import get_global_debugger debugger = get_global_debugger() if debugger is not None: pydevd_tracing.SetTrace(debugger.trace_dispatch)
def _schedule_callback(prev, next): ''' Called when a context is stopped or a new context is made runnable. ''' try: if not prev and not next: return current_frame = sys._getframe() if next: register_tasklet_info(next) # Ok, making next runnable: set the tracing facility in it. debugger = get_global_debugger() if debugger is not None: next.trace_function = debugger.get_thread_local_trace_func() frame = next.frame if frame is current_frame: frame = frame.f_back if hasattr(frame, 'f_trace'): # Note: can be None (but hasattr should cover for that too). frame.f_trace = debugger.get_thread_local_trace_func() debugger = None if prev: register_tasklet_info(prev) try: for tasklet_ref, tasklet_info in dict_items(_weak_tasklet_registered_to_info): # Make sure it's a copy! tasklet = tasklet_ref() if tasklet is None or not tasklet.alive: # Garbage-collected already! try: del _weak_tasklet_registered_to_info[tasklet_ref] except KeyError: pass if tasklet_info.frame_id is not None: remove_custom_frame(tasklet_info.frame_id) else: is_running = stackless.get_thread_info(tasklet.thread_id)[1] is tasklet if tasklet is prev or (tasklet is not next and not is_running): # the tasklet won't run after this scheduler action: # - the tasklet is the previous tasklet # - it is not the next tasklet and it is not an already running tasklet frame = tasklet.frame if frame is current_frame: frame = frame.f_back if frame is not None: abs_real_path_and_base = get_abs_path_real_path_and_base_from_frame(frame) # print >>sys.stderr, "SchedCB: %r, %d, '%s', '%s'" % (tasklet, frame.f_lineno, _filename, base) if debugger.get_file_type(abs_real_path_and_base) is None: tasklet_info.update_name() if tasklet_info.frame_id is None: tasklet_info.frame_id = add_custom_frame(frame, tasklet_info.tasklet_name, tasklet.thread_id) else: update_custom_frame(tasklet_info.frame_id, frame, tasklet.thread_id, name=tasklet_info.tasklet_name) elif tasklet is next or is_running: if tasklet_info.frame_id is not None: # Remove info about stackless suspended when it starts to run. remove_custom_frame(tasklet_info.frame_id) tasklet_info.frame_id = None finally: tasklet = None tasklet_info = None frame = None except: import traceback;traceback.print_exc() if _application_set_schedule_callback is not None: return _application_set_schedule_callback(prev, next)
def set_trace_in_qt(): from _pydevd_bundle.pydevd_comm import get_global_debugger debugger = get_global_debugger() if debugger is not None: threading.current_thread() # Create the dummy thread for qt. debugger.enable_tracing()
def send_process_created_message(): from _pydevd_bundle.pydevd_comm import get_global_debugger debugger = get_global_debugger() if debugger is not None: debugger.send_process_created_message()