def child(): import os from debuggee import backchannel backchannel.send(os.getpid()) backchannel.receive() backchannel.send("ok")
def test_run(pyfile, target, run): @pyfile def code_to_debug(): import os import sys import debuggee from debuggee import backchannel debuggee.setup() print("begin") backchannel.send(os.path.abspath(sys.modules["debugpy"].__file__)) assert backchannel.receive() == "continue" print("end") with debug.Session() as session: backchannel = session.open_backchannel() with run(session, target(code_to_debug)): pass expected_debugpy_path = os.path.abspath(debugpy.__file__) assert backchannel.receive() == some.str.matching( re.escape(expected_debugpy_path) + r"(c|o)?") backchannel.send("continue") session.wait_for_next_event("terminated") session.proceed()
def code_to_debug(): import sys import debuggee from debuggee import backchannel debuggee.setup() backchannel.send(sys.executable)
def test_nodebug(pyfile, run, target): @pyfile def code_to_debug(): import debuggee from debuggee import backchannel debuggee.setup() backchannel.receive() # @ bp1 print("ok") # @ bp2 with debug.Session() as session: session.config["noDebug"] = True session.config["redirectOutput"] = True backchannel = session.open_backchannel() run(session, target(code_to_debug)) with pytest.raises(messaging.MessageHandlingError): session.set_breakpoints(code_to_debug, all) backchannel.send(None) # Breakpoint shouldn't be hit. pass assert "ok" in session.output("stdout")
def child(): import os from debuggee import backchannel backchannel.send(os.getpid()) while True: pass
def code_to_debug(): import debuggee from debuggee import backchannel debuggee.setup() a = 1 backchannel.send(a) # @bp
def code_to_debug(): import sys import debuggee from debuggee import backchannel debuggee.setup() backchannel.send(sys.stdin == sys.__stdin__)
def parent(q, a): from debuggee import backchannel debuggee.setup() print("spawning child") p = multiprocessing.Process(target=child, args=(q, a)) p.start() print("child spawned") q.put("foo?") foo = a.get() assert isinstance(foo, Foo), repr(foo) q.put("child_pid?") what, child_pid = a.get() assert what == "child_pid" backchannel.send(child_pid) q.put("grandchild_pid?") what, grandchild_pid = a.get() assert what == "grandchild_pid" backchannel.send(grandchild_pid) assert backchannel.receive() == "continue" q.put("exit!") p.join()
def code_to_debug(): import os import debuggee from debuggee import backchannel debuggee.setup() backchannel.send(os.getenv("DEBUGPY_CUSTOM_PYTHON"))
def code_to_debug(): import sys import debuggee from debuggee import backchannel debuggee.setup() backchannel.send([sys.flags.optimize, sys.flags.dont_write_bytecode])
def code_to_debug(): import sys import debuggee from debuggee import backchannel debuggee.setup() backchannel.send( [sys.executable, sys.flags.optimize, sys.flags.verbose])
def code_to_debug(): import os import debuggee from debuggee import backchannel debuggee.setup() backchannel.send(dict(os.environ))
def code_to_debug(): import os import debuggee from debuggee import backchannel debuggee.setup() backchannel.send(os.path.abspath(__file__)) print("done") # @bp
def code_to_debug(): import os import debuggee from debuggee import backchannel debuggee.setup() backchannel.send(os.getenv("DEBUGPY_SUDO", "0"))
def test_breakaway_job(pyfile, target, run): @pyfile def child(): import os from debuggee import backchannel backchannel.send(os.getpid()) backchannel.receive() backchannel.send("ok") @pyfile def parent(): import debuggee import os import subprocess import sys debuggee.setup() argv = [sys.executable, sys.argv[1]] env = os.environ.copy() pipe_in = open(os.devnull, "r") pipe_out = open(os.devnull, "w") CREATE_BREAKAWAY_FROM_JOB = 0x01000000 proc = subprocess.Popen( argv, env=env, stdin=pipe_in, stdout=pipe_out, stderr=pipe_out, creationflags=CREATE_BREAKAWAY_FROM_JOB, ) pipe_in.close() pipe_out.close() proc.wait() with debug.Session() as parent_session: parent_session.config.update({ "redirectOutput": False, "subProcess": False, }) parent_session.expected_exit_code = some.int backchannel = parent_session.open_backchannel() with run(parent_session, target(parent, args=[child])): pass child_pid = backchannel.receive() child_process = psutil.Process(child_pid) parent_session.request("terminate") parent_session.wait_for_exit() # child should still be running backchannel.send("proceed") assert backchannel.receive() == "ok" log.info("Waiting for child process...") child_process.wait()
def code_to_debug(): import debuggee from debuggee import backchannel debuggee.setup() from _pydevd_frame_eval.pydevd_frame_eval_main import USING_FRAME_EVAL backchannel.send(USING_FRAME_EVAL)
def code_to_debug(): import debuggee import debugpy from debuggee import backchannel debuggee.setup() a = 1 debugpy.breakpoint() backchannel.send(a)
def child(): import sys from debuggee import backchannel from args import args as expected_args backchannel.send(expected_args) actual_args = sys.argv[1:] backchannel.send(actual_args)
def test_subprocess_unobserved(pyfile, run, target, wait): @pyfile def child(): from debuggee import backchannel # @bp backchannel.send("child running") backchannel.receive() @pyfile def parent(): import debuggee import os import subprocess import sys debuggee.setup() args = [sys.executable, sys.argv[1]] env = os.environ.copy() subprocess.Popen(args, env=env).wait() with debug.Session() as parent_session: backchannel = parent_session.open_backchannel() if not wait: # The child process should have started running user code as soon as it's # spawned, before there is a client connection. def before_connect(address): assert backchannel.receive() == "child running" parent_session.before_connect = before_connect with run(parent_session, target(parent, args=[child]), wait=bool(wait)): pass child_config = parent_session.wait_for_next_event("debugpyAttach") parent_session.proceed() with debug.Session(child_config) as child_session: with child_session.start(): child_session.set_breakpoints(child, all) if wait: # The child process should not have started running user code until # there was a client connection, so the breakpoint should be hit. child_session.wait_for_stop( expected_frames=[some.dap.frame(child, line="bp")]) child_session.request_continue() else: # The breakpoint shouldn't be hit, since that line should have been # executed before we attached. pass backchannel.send("proceed") child_session.wait_for_terminated()
def code_to_debug(): import debuggee from debuggee import backchannel from _pydev_bundle.pydev_log import list_log_files debuggee.setup() from _pydevd_bundle import pydevd_constants # @ bp1 backchannel.send( list_log_files(pydevd_constants.DebugInfoHolder.PYDEVD_DEBUG_FILE) ) assert backchannel.receive() == "continue"
def code_to_debug(): import os import sys import debuggee from debuggee import backchannel debuggee.setup() print("begin") backchannel.send(os.path.abspath(sys.modules["debugpy"].__file__)) assert backchannel.receive() == "continue" print("end")
def code_to_debug(): import debuggee import debugpy import sys import time from debuggee import backchannel, scratchpad debuggee.setup() _, host, port, wait_for_client, is_client_connected, stop_method = sys.argv port = int(port) debugpy.listen(address=(host, port)) if wait_for_client: backchannel.send("wait_for_client") debugpy.wait_for_client() if is_client_connected: backchannel.send("is_client_connected") while not debugpy.is_client_connected(): print("looping until is_client_connected()") time.sleep(0.1) if stop_method == "breakpoint": backchannel.send("breakpoint?") assert backchannel.receive() == "proceed" debugpy.breakpoint() print("break") # @breakpoint else: scratchpad["paused"] = False backchannel.send("loop?") assert backchannel.receive() == "proceed" while not scratchpad["paused"]: print("looping until paused") time.sleep(0.1)
def code_to_debug(): import debuggee import os import sys from debuggee import backchannel debuggee.setup() backchannel.send(os.path.abspath(__file__)) call_me_back_dir = backchannel.receive() sys.path.insert(0, call_me_back_dir) import call_me_back def call_func(): print("break here") # @bp call_me_back.call_me_back(call_func) # @call_me_back print("done")
def test_run_relative_path(pyfile, run): @pyfile def code_to_debug(): import debuggee from debuggee import backchannel from _pydev_bundle.pydev_log import list_log_files debuggee.setup() from _pydevd_bundle import pydevd_constants # @ bp1 backchannel.send( list_log_files(pydevd_constants.DebugInfoHolder.PYDEVD_DEBUG_FILE) ) assert backchannel.receive() == "continue" with debug.Session() as session: backchannel = session.open_backchannel() code_to_debug = str(code_to_debug) cwd = os.path.dirname(os.path.dirname(code_to_debug)) program = targets.Program(code_to_debug) program.make_relative(cwd) with run(session, program): session.set_breakpoints(code_to_debug, all) session.wait_for_stop() session.request_continue() pydevd_debug_files = backchannel.receive() backchannel.send("continue") session.wait_for_next_event("terminated") session.proceed() # Check if we don't have errors in the pydevd log (the # particular error this test is covering: # https://github.com/microsoft/debugpy/issues/620 # is handled by pydevd but produces a Traceback in the logs). for pydevd_debug_file in pydevd_debug_files: with open(pydevd_debug_file, "r") as stream: contents = stream.read() assert "critical" not in contents assert "Traceback" not in contents
def test_log_dir_env(pyfile, tmpdir, run, target): @pyfile def code_to_debug(): import debuggee from debuggee import backchannel debuggee.setup() assert backchannel.receive() == "proceed" with check_logs(tmpdir, run, pydevd_log=True): with debug.Session() as session: session.log_dir = None session.spawn_adapter.env["DEBUGPY_LOG_DIR"] = tmpdir if run.request != "launch": session.spawn_debuggee.env["DEBUGPY_LOG_DIR"] = tmpdir backchannel = session.open_backchannel() with run(session, target(code_to_debug)): pass backchannel.send("proceed")
def child(): import os import sys assert "debugpy" in sys.modules import debugpy from debuggee import backchannel backchannel.send(os.getpid()) backchannel.send(debugpy.__file__) backchannel.send(sys.argv)
def test_with_path_mappings(pyfile, long_tmpdir, target, run): @pyfile def code_to_debug(): import debuggee import os import sys from debuggee import backchannel debuggee.setup() backchannel.send(os.path.abspath(__file__)) call_me_back_dir = backchannel.receive() sys.path.insert(0, call_me_back_dir) import call_me_back def call_func(): print("break here") # @bp call_me_back.call_me_back(call_func) # @call_me_back print("done") dir_local = long_tmpdir.mkdir("local") dir_remote = long_tmpdir.mkdir("remote") path_local = dir_local / "code_to_debug.py" path_remote = dir_remote / "code_to_debug.py" code_to_debug.copy(path_local) code_to_debug.copy(path_remote) call_me_back_dir = test_data / "call_me_back" call_me_back_py = call_me_back_dir / "call_me_back.py" with debug.Session() as session: session.config["pathMappings"] = [{ "localRoot": dir_local, "remoteRoot": dir_remote }] backchannel = session.open_backchannel() with run(session, target(path_remote)): # Set breakpoints using local path. This tests that local paths are # mapped to remote paths. session.set_breakpoints(path_local, ["bp"]) actual_path_remote = backchannel.receive() assert some.path(actual_path_remote) == path_remote backchannel.send(call_me_back_dir) stop = session.wait_for_stop( "breakpoint", expected_frames=[ some.dap.frame( # Mapped files should not have a sourceReference, so that the IDE # doesn't try to fetch them instead of opening the local file. some.dap.source(path_local, sourceReference=0), line="bp", ), some.dap.frame( # Unmapped files should have a sourceReference, since there's no # local file for the IDE to open. some.dap.source(call_me_back_py, sourceReference=some.int.not_equal_to(0)), line="callback", ), some.dap.frame( # Mapped files should not have a sourceReference, so that the IDE # doesn't try to fetch them instead of opening the local file. some.dap.source(path_local, sourceReference=0), line="call_me_back", ), ], ) srcref = stop.frames[1]["source"]["sourceReference"] try: session.request("source", {"sourceReference": 0}) except Exception as exc: assert "Source unavailable" in str(exc) else: pytest.fail("sourceReference=0 should not be valid") source = session.request("source", {"sourceReference": srcref}) assert "def call_me_back(callback):" in source["content"] session.request_continue()
def code_to_debug(): import debuggee from debuggee import backchannel debuggee.setup() backchannel.send("continued") # @bp
def code_to_debug(): from debuggee import backchannel # @bp backchannel.send("done")
def test_attach_api(pyfile, target, wait_for_client, is_client_connected, stop_method): @pyfile def code_to_debug(): import debuggee import debugpy import sys import time from debuggee import backchannel, scratchpad debuggee.setup() _, host, port, wait_for_client, is_client_connected, stop_method = sys.argv port = int(port) debugpy.listen(address=(host, port)) if wait_for_client: backchannel.send("wait_for_client") debugpy.wait_for_client() if is_client_connected: backchannel.send("is_client_connected") while not debugpy.is_client_connected(): print("looping until is_client_connected()") time.sleep(0.1) if stop_method == "breakpoint": backchannel.send("breakpoint?") assert backchannel.receive() == "proceed" debugpy.breakpoint() print("break") # @breakpoint else: scratchpad["paused"] = False backchannel.send("loop?") assert backchannel.receive() == "proceed" while not scratchpad["paused"]: print("looping until paused") time.sleep(0.1) with debug.Session() as session: host, port = runners.attach_connect.host, runners.attach_connect.port session.config.update({"connect": {"host": host, "port": port}}) backchannel = session.open_backchannel() session.spawn_debuggee([ code_to_debug, host, port, wait_for_client, is_client_connected, stop_method, ]) session.wait_for_adapter_socket() session.connect_to_adapter((host, port)) with session.request_attach(): pass if wait_for_client: assert backchannel.receive() == "wait_for_client" if is_client_connected: assert backchannel.receive() == "is_client_connected" if stop_method == "breakpoint": assert backchannel.receive() == "breakpoint?" backchannel.send("proceed") session.wait_for_stop( expected_frames=[some.dap.frame(code_to_debug, "breakpoint")]) elif stop_method == "pause": assert backchannel.receive() == "loop?" backchannel.send("proceed") session.request("pause", freeze=False) session.wait_for_stop("pause") session.scratchpad["paused"] = True else: pytest.fail(stop_method) session.request_continue()