def debug(address, **kwargs): if _settrace.called: raise RuntimeError("this process already has a debug adapter") try: _, port = address except Exception: port = address address = ("127.0.0.1", port) try: port.__index__() # ensure it's int-like except Exception: raise ValueError("expected port or (host, port)") if not (0 <= port < 2**16): raise ValueError("invalid port number") ensure_logging() log.debug("{0}({1!r}, **{2!r})", func.__name__, address, kwargs) log.info("Initial debug configuration: {0!j}", _config) settrace_kwargs = { "suspend": False, "patch_multiprocessing": _config.get("subProcess", True), } debugpy_path, _, _ = get_abs_path_real_path_and_base_from_file( debugpy.__file__) debugpy_path = os.path.dirname(debugpy_path) settrace_kwargs["dont_trace_start_patterns"] = (debugpy_path, ) settrace_kwargs["dont_trace_end_patterns"] = ("debugpy_launcher.py", ) try: return func(address, settrace_kwargs, **kwargs) except Exception: log.reraise_exception("{0}() failed:", func.__name__, level="info")
def configure(properties, **kwargs): if _settrace.called: raise RuntimeError("debug adapter is already running") ensure_logging() log.debug("configure{0!r}", (properties, kwargs)) if properties is None: properties = kwargs else: properties = dict(properties) properties.update(kwargs) for k, v in properties.items(): if k not in _config: raise ValueError(fmt("Unknown property {0!r}", k)) expected_type = type(_config[k]) if type(v) is not expected_type: raise ValueError( fmt("{0!r} must be a {1}", k, expected_type.__name__)) valid_values = _config_valid_values.get(k) if (valid_values is not None) and (v not in valid_values): raise ValueError( fmt("{0!r} must be one of: {1!r}", k, valid_values)) _config[k] = v
def close(self): sock = self._socket if sock: self._socket = None log.debug("Closing {0} client socket...", self) try: sock.shutdown(socket.SHUT_RDWR) except Exception: pass try: sock.close() except Exception: pass server_socket = self._server_socket if server_socket: self._server_socket = None log.debug("Closing {0} server socket...", self) try: server_socket.shutdown(socket.SHUT_RDWR) except Exception: pass try: server_socket.close() except Exception: pass
def __init__(self, component, message): """Parses an "initialize" request or response and extracts the feature flags. For every "X" in self.PROPERTIES, sets self["X"] to the corresponding value from message.payload if it's present there, or to the default value otherwise. """ assert message.is_request("initialize") or message.is_response("initialize") self.component = component payload = message.payload for name, validate in self.PROPERTIES.items(): value = payload.get(name, ()) if not callable(validate): validate = json.default(validate) try: value = validate(value) except Exception as exc: raise message.isnt_valid("{0!j} {1}", name, exc) assert value != (), fmt( "{0!j} must provide a default value for missing properties.", validate ) self[name] = value log.debug("{0}", self)
def _propagate_deferred_events(self): log.debug("Propagating deferred events to {0}...", self.client) for event in self._deferred_events: log.debug("Propagating deferred {0}", event.describe()) self.client.channel.propagate(event) log.info("All deferred events propagated to {0}.", self.client) self._deferred_events = None
def _settrace(*args, **kwargs): log.debug("pydevd.settrace(*{0!r}, **{1!r})", args, kwargs) try: return pydevd.settrace(*args, **kwargs) except Exception: raise else: _settrace.called = True
def trace_this_thread(should_trace): ensure_logging() log.debug("trace_this_thread({0!r})", should_trace) pydb = get_global_debugger() if should_trace: pydb.enable_tracing() else: pydb.disable_tracing()
def log_to(path): if ensure_logging.ensured: raise RuntimeError("logging has already begun") log.debug("log_to{0!r}", (path,)) if path is sys.stderr: log.stderr.levels |= set(log.LEVELS) else: log.log_dir = path
def propagate_after_start(self, event): # pydevd starts sending events as soon as we connect, but the client doesn't # expect to see any until it receives the response to "launch" or "attach" # request. If client is not ready yet, save the event instead of propagating # it immediately. if self._deferred_events is not None: self._deferred_events.append(event) log.debug("Propagation deferred.") else: self.client.channel.propagate(event)
def wait(self, timeout=None): """Wait for all remaining output to be captured. """ if not self._worker_threads: return log.debug("Waiting for remaining {0} output...", self.session.debuggee_id) for t in self._worker_threads: t.join(timeout) self._worker_threads[:] = []
def _settrace(*args, **kwargs): log.debug("pydevd.settrace(*{0!r}, **{1!r})", args, kwargs) # The stdin in notification is not acted upon in debugpy, so, disable it. kwargs.setdefault('notify_stdin', False) try: return pydevd.settrace(*args, **kwargs) except Exception: raise else: _settrace.called = True
def wait_for_client(): ensure_logging() log.debug("wait_for_client()") pydb = get_global_debugger() if pydb is None: raise RuntimeError("listen() or connect() must be called first") cancel_event = threading.Event() debugpy.wait_for_client.cancel = wait_for_client.cancel = cancel_event.set pydevd._wait_for_attach(cancel=cancel_event)
def run_file(): start_debugging(options.target) # run_path has one difference with invoking Python from command-line: # if the target is a file (rather than a directory), it does not add its # parent directory to sys.path. Thus, importing other modules from the # same directory is broken unless sys.path is patched here. if os.path.isfile(options.target): dir = os.path.dirname(options.target) sys.path.insert(0, dir) else: log.debug("Not a file: {0!r}", options.target) log.describe_environment("Pre-launch environment:") log.info("Running file {0!r}", options.target) runpy.run_path(options.target, run_name=compat.force_str("__main__"))
def start_debugging(argv_0): # We need to set up sys.argv[0] before invoking either listen() or connect(), # because they use it to report the "process" event. Thus, we can't rely on # run_path() and run_module() doing that, even though they will eventually. sys.argv[0] = compat.filename_str(argv_0) log.debug("sys.argv after patching: {0!r}", sys.argv) debugpy.configure(options.config) if options.mode == "listen": debugpy.listen(options.address) elif options.mode == "connect": debugpy.connect(options.address, access_token=options.adapter_access_token) else: raise AssertionError(repr(options.mode)) if options.wait_for_client: debugpy.wait_for_client()
def breakpoint(): ensure_logging() if not is_client_connected(): log.info("breakpoint() ignored - debugger not attached") return log.debug("breakpoint()") # Get the first frame in the stack that's not an internal frame. pydb = get_global_debugger() stop_at_frame = sys._getframe().f_back while (stop_at_frame is not None and pydb.get_file_type(stop_at_frame) == pydb.PYDEV_FILE): stop_at_frame = stop_at_frame.f_back _settrace( suspend=True, trace_only_current_thread=True, patch_multiprocessing=False, stop_at_frame=stop_at_frame, ) stop_at_frame = None
def _wait_for_user_input(): if sys.stdout and sys.stdin and sys.stdin.isatty(): from debugpy.common import log try: import msvcrt except ImportError: can_getch = False else: can_getch = True if can_getch: log.debug("msvcrt available - waiting for user input via getch()") sys.stdout.write("Press any key to continue . . . ") sys.stdout.flush() msvcrt.getch() else: log.debug("msvcrt not available - waiting for user input via read()") sys.stdout.write("Press Enter to continue . . . ") sys.stdout.flush() sys.stdin.read(1)
def parse(args): log.debug("Parsing argv: {0!r}", args) try: output = subprocess.check_output( [sys.executable, "-u", cli_parser.strpath] + args) argv, options = pickle.loads(output) except subprocess.CalledProcessError as exc: raise pickle.loads(exc.output) log.debug("Adjusted sys.argv: {0!r}", argv) log.debug("Parsed options: {0!r}", options) return argv, options
def worker(): messages = MessageFactory() worker_can_proceed.wait() worker_can_proceed.clear() timeline.record_event(messages.event("dum", {})) log.debug("dum") worker_can_proceed.wait() timeline.record_event(messages.event("dee", {})) log.debug("dee") timeline.record_event(messages.event("dum", {})) log.debug("dum")
def _log_message(self, dir, data): format_string = "{0} {1} " + ("{2!j:indent=None}" if isinstance( data, list) else "{2!j}") return log.debug(format_string, self.name, dir, data)
def impl(result, func, args): if is_error_result(result): log.debug("{0} returned {1}", func.__name__, result) raise ctypes.WinError() else: return result
def debug_this_thread(): ensure_logging() log.debug("debug_this_thread()") _settrace(suspend=False)