Пример #1
0
    def code_to_debug():
        from debug_me import backchannel
        from os import path
        import sys

        print("begin")
        backchannel.send(path.abspath(sys.modules["ptvsd"].__file__))
        assert backchannel.receive() == "continue"
        print("end")
Пример #2
0
    def child():
        from debug_me import backchannel
        import sys

        from args import args as expected_args

        backchannel.send(expected_args)

        actual_args = sys.argv[1:]
        backchannel.send(actual_args)
Пример #3
0
    def code_to_debug():
        from debug_me import backchannel, ptvsd, scratchpad
        import sys
        import time

        _, host, port, wait_for_attach, is_attached, stop_method = sys.argv
        port = int(port)
        ptvsd.enable_attach((host, port))

        if wait_for_attach:
            backchannel.send("wait_for_attach")
            ptvsd.wait_for_attach()

        if is_attached:
            backchannel.send("is_attached")
            while not ptvsd.is_attached():
                print("looping until is_attached")
                time.sleep(0.1)

        if stop_method == "break_into_debugger":
            backchannel.send("break_into_debugger?")
            assert backchannel.receive() == "proceed"
            ptvsd.break_into_debugger()
            print("break")  # @break_into_debugger
        else:
            scratchpad["paused"] = False
            backchannel.send("loop?")
            assert backchannel.receive() == "proceed"
            while not scratchpad["paused"]:
                print("looping until paused")
                time.sleep(0.1)
Пример #4
0
    def code_to_debug():
        from debug_me import backchannel
        import os
        import sys

        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")
Пример #5
0
    def code_to_debug():
        import multiprocessing
        import platform
        import sys
        import debug_me  # noqa

        def child_of_child(q):
            print("entering child of child")
            assert q.get() == 2
            q.put(3)
            print("leaving child of child")

        def child(q):
            print("entering child")
            assert q.get() == 1

            print("spawning child of child")
            p = multiprocessing.Process(target=child_of_child, args=(q, ))
            p.start()
            p.join()

            assert q.get() == 3
            q.put(4)
            print("leaving child")

        if __name__ == "__main__":
            from debug_me import backchannel

            if sys.version_info >= (3, 4):
                multiprocessing.set_start_method("spawn")
            else:
                assert platform.system() == "Windows"

            print("spawning child")
            q = multiprocessing.Queue()
            p = multiprocessing.Process(target=child, args=(q, ))
            p.start()
            print("child spawned")
            backchannel.send(p.pid)

            q.put(1)
            assert backchannel.receive() == "continue"
            q.put(2)
            p.join()
            assert q.get() == 4
            q.close()
            backchannel.send("done")
Пример #6
0
def test_log_dir_env(pyfile, tmpdir, run, target):
    @pyfile
    def code_to_debug():
        from debug_me import backchannel  # noqa

        assert backchannel.receive() == "proceed"

    with check_logs(tmpdir, run):
        with debug.Session() as session:
            session.log_dir = None
            session.spawn_adapter.env["PTVSD_LOG_DIR"] = tmpdir
            if run.request != "launch":
                session.spawn_debuggee.env["PTVSD_LOG_DIR"] = tmpdir

            backchannel = session.open_backchannel()
            with run(session, target(code_to_debug)):
                pass

            backchannel.send("proceed")
Пример #7
0
        def parent(q, a):
            from debug_me import backchannel

            print("spawning child")
            p = multiprocessing.Process(target=child, args=(q, a))
            p.start()
            print("child spawned")

            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()
Пример #8
0
def test_nodebug(pyfile, run, target):
    @pyfile
    def code_to_debug():
        from debug_me import backchannel

        backchannel.receive()  # @ bp1
        print("ok")  # @ bp2

    with debug.Session() as session:
        session.config["noDebug"] = 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")
Пример #9
0
def test_run(pyfile, target, run):
    @pyfile
    def code_to_debug():
        from debug_me import backchannel
        from os import path
        import sys

        print("begin")
        backchannel.send(path.abspath(sys.modules["ptvsd"].__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_ptvsd_path = path.abspath(ptvsd.__file__)
        assert backchannel.receive() == some.str.matching(
            re.escape(expected_ptvsd_path) + r"(c|o)?")

        backchannel.send("continue")
        session.wait_for_next_event("terminated")
        session.proceed()
Пример #10
0
    def child():
        import os
        import sys

        assert "ptvsd" in sys.modules

        from debug_me import backchannel, ptvsd

        backchannel.send(os.getpid())
        backchannel.send(ptvsd.__file__)
        backchannel.send(sys.argv)
Пример #11
0
    def code_to_debug():
        from debug_me import backchannel

        backchannel.send("continued")  # @bp
Пример #12
0
def test_with_path_mappings(pyfile, long_tmpdir, target, run):
    @pyfile
    def code_to_debug():
        from debug_me import backchannel
        import os
        import sys

        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 ex:
            assert "Source unavailable" in str(ex)
        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()
Пример #13
0
    def code_to_debug():
        from debug_me import backchannel
        import os

        backchannel.send(os.path.abspath(__file__))
        print("done")  # @bp
Пример #14
0
    def code_to_debug():
        from debug_me import backchannel  # @bp

        backchannel.send("done")
Пример #15
0
    def code_to_debug():
        from debug_me import backchannel

        a = 1
        backchannel.send(a)  # @bp
Пример #16
0
    def code_to_debug():
        from debug_me import backchannel
        import sys

        backchannel.send(sys.argv)
Пример #17
0
def test_attach_api(pyfile, target, wait_for_attach, is_attached, stop_method):
    @pyfile
    def code_to_debug():
        from debug_me import backchannel, ptvsd, scratchpad
        import sys
        import time

        _, host, port, wait_for_attach, is_attached, stop_method = sys.argv
        port = int(port)
        ptvsd.enable_attach((host, port))

        if wait_for_attach:
            backchannel.send("wait_for_attach")
            ptvsd.wait_for_attach()

        if is_attached:
            backchannel.send("is_attached")
            while not ptvsd.is_attached():
                print("looping until is_attached")
                time.sleep(0.1)

        if stop_method == "break_into_debugger":
            backchannel.send("break_into_debugger?")
            assert backchannel.receive() == "proceed"
            ptvsd.break_into_debugger()
            print("break")  # @break_into_debugger
        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_by_socket.host, runners.attach_by_socket.port
        session.config.update({"host": host, "port": port})

        backchannel = session.open_backchannel()
        session.spawn_debuggee([
            code_to_debug, host, port, wait_for_attach, is_attached,
            stop_method
        ])
        session.wait_for_enable_attach()

        session.connect_to_adapter((host, port))
        with session.request_attach():
            pass

        if wait_for_attach:
            assert backchannel.receive() == "wait_for_attach"

        if is_attached:
            assert backchannel.receive() == "is_attached"

        if stop_method == "break_into_debugger":
            assert backchannel.receive() == "break_into_debugger?"
            backchannel.send("proceed")
            session.wait_for_stop(expected_frames=[
                some.dap.frame(code_to_debug, "break_into_debugger")
            ])
        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()
Пример #18
0
def test_exceptions_and_partial_exclude_rules(pyfile, target, run, scenario):
    @pyfile
    def code_to_debug():
        from debug_me import backchannel
        import sys

        call_me_back_dir = backchannel.receive()
        sys.path.insert(0, call_me_back_dir)

        import call_me_back

        def call_func():
            raise RuntimeError("unhandled error")  # @raise

        call_me_back.call_me_back(call_func)  # @call_me_back
        print("done")

    call_me_back_dir = test_data / "call_me_back"
    call_me_back_py = call_me_back_dir / "call_me_back.py"
    call_me_back_py.lines = code.get_marked_line_numbers(call_me_back_py)

    if scenario == "exclude_code_to_debug":
        rules = [{"path": "**/" + code_to_debug.basename, "include": False}]
    elif scenario == "exclude_callback_dir":
        rules = [{"path": call_me_back_dir, "include": False}]
    else:
        pytest.fail(scenario)
    log.info("Rules: {0!j}", rules)

    with debug.Session() as session:
        session.expected_exit_code = some.int
        session.config["rules"] = rules

        backchannel = session.open_backchannel()
        with run(session, target(code_to_debug)):
            session.request(
                "setExceptionBreakpoints", {"filters": ["raised", "uncaught"]}
            )

        backchannel.send(call_me_back_dir)

        if scenario == "exclude_code_to_debug":
            # Stop at handled exception, with code_to_debug.py excluded.
            #
            # Since the module raising the exception is excluded, it must not stop at
            # @raise, but rather at @callback (i.e. the closest non-excluded frame).

            stop = session.wait_for_stop(
                "exception",
                expected_frames=[
                    some.dap.frame(
                        some.dap.source(call_me_back_py),
                        line=call_me_back_py.lines["callback"],
                    )
                ],
            )
            assert stop.frames != some.list.containing(
                [some.dap.frame(some.dap.source(code_to_debug), line=some.int)]
            )

            # As exception unwinds the stack, we shouldn't stop at @call_me_back,
            # since that line is in the excluded file. Furthermore, although the
            # exception is unhandled, we shouldn't get a stop for that, either,
            # because the exception is last seen in an excluded file.
            session.request_continue()

        elif scenario == "exclude_callback_dir":
            # Stop at handled exception, with call_me_back.py excluded.
            #
            # Since the module raising the exception is not excluded, it must stop at
            # @raise.

            stop = session.wait_for_stop(
                "exception",
                expected_frames=[
                    some.dap.frame(
                        some.dap.source(code_to_debug),
                        name="call_func",
                        line=code_to_debug.lines["raise"],
                    ),
                    some.dap.frame(
                        some.dap.source(code_to_debug),
                        name="<module>",
                        line=code_to_debug.lines["call_me_back"],
                    ),
                ],
            )
            assert stop.frames != some.list.containing(
                [some.dap.frame(some.dap.source(call_me_back_py), line=some.int)]
            )

            session.request_continue()

            # As exception unwinds the stack, it must not stop at @callback, since that
            # line is in the excluded file. However, it must stop at @call_me_back.
            stop = session.wait_for_stop(
                "exception",
                expected_frames=[
                    some.dap.frame(
                        some.dap.source(code_to_debug),
                        name="<module>",
                        line=code_to_debug.lines["call_me_back"],
                    )
                ],
            )
            assert stop.frames != some.list.containing(
                [some.dap.frame(some.dap.source(call_me_back_py), line=some.int)]
            )

            session.request_continue()

            # Now the exception is unhandled, and should be reported as such.
            stop = session.wait_for_stop(
                "exception",
                expected_frames=[
                    some.dap.frame(
                        some.dap.source(code_to_debug),
                        name="call_func",
                        line=code_to_debug.lines["raise"],
                    ),
                    some.dap.frame(
                        some.dap.source(code_to_debug),
                        name="<module>",
                        line=code_to_debug.lines["call_me_back"],
                    ),
                ],
            )
            assert stop.frames != some.list.containing(
                [some.dap.frame(some.dap.source(call_me_back_py), line=some.int)]
            )

            # Let the process crash due to unhandled exception.
            session.request_continue()

        else:
            pytest.fail(scenario)
Пример #19
0
    def child():
        import sys
        from debug_me import backchannel

        backchannel.send(sys.argv)
Пример #20
0
    def code_to_debug():
        from debug_me import backchannel, ptvsd

        a = 1
        ptvsd.break_into_debugger()
        backchannel.send(a)
Пример #21
0
from debug_me import backchannel

backchannel.send("ok")