Example #1
0
def test_redirect_output(pyfile, run_as, start_method, redirect):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()

        for i in [111, 222, 333, 444]:
            print(i)

        print()  # @bp1

    line_numbers = get_marked_line_numbers(code_to_debug)
    with DebugSession() as session:
        # By default 'RedirectOutput' is always set. So using this way
        #  to override the default in session.
        session.debug_options = [redirect] if bool(redirect) else []
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
        )

        session.set_breakpoints(code_to_debug, [line_numbers['bp1']])
        session.start_debugging()

        # Breakpoint at the end just to make sure we get all output events.
        session.wait_for_thread_stopped()
        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()

        output = session.all_occurrences_of(
            Event('output', ANY.dict_with({'category': 'stdout'})))
        expected = ['111', '222', '333', '444'] if bool(redirect) else []
        assert expected == list(o.body['output'] for o in output
                                if len(o.body['output']) == 3)
Example #2
0
def test_run_vs(pyfile, run_as):
    @pyfile
    def code_to_debug():
        # import_and_enable_debugger
        import backchannel
        backchannel.write_json('ok')

    @pyfile
    def ptvsd_launcher():
        # import_and_enable_debugger
        import ptvsd.debugger
        import backchannel
        args = tuple(backchannel.read_json())
        print('debug%r' % (args, ))
        ptvsd.debugger.debug(*args)

    with DebugSession() as session:
        filename = 'code_to_debug' if run_as == 'module' else code_to_debug
        session.before_connect = lambda: session.write_json(
            [filename, session.ptvsd_port, None, None, run_as])

        session.initialize(target=('file', ptvsd_launcher),
                           start_method='custom_client',
                           use_backchannel=True)
        session.start_debugging()
        assert session.read_json() == 'ok'
        session.wait_for_exit()
Example #3
0
def test_ptvsd_systeminfo(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        a = 'hello'  # @bp1
        print(a)

    line_numbers = get_marked_line_numbers(code_to_debug)
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
        )

        session.set_breakpoints(code_to_debug, [line_numbers['bp1']])
        session.start_debugging()

        session.wait_for_thread_stopped()

        resp = session.send_request('ptvsd_systemInfo').wait_for_response()
        expected = _generate_system_info()
        assert resp.body == expected

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Example #4
0
def test_attaching_by_pid_no_threading(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        # import_and_enable_debugger
        import time

        wait = True
        i = 0
        while wait:
            i += 1
            print('in loop')
            time.sleep(0.1)
            if i > 100:
                raise AssertionError(
                    'Debugger did not change wait to False as expected within the timeout.'
                )

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
        )
        session.start_debugging()
        # Wait for the first print to make sure we're in the proper state to pause.
        session.wait_for_next(
            Event('output',
                  ANY.dict_with({
                      'category': 'stdout',
                      'output': 'in loop'
                  })))
        _change_wait_to_false_and_exit(session)
Example #5
0
def test_set_variable(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        import backchannel
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        import ptvsd
        a = 1
        ptvsd.break_into_debugger()
        backchannel.write_json(a)

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            ignore_unobserved=[Event('continued')],
            use_backchannel=True,
        )
        session.start_debugging()
        hit = session.wait_for_thread_stopped()

        resp_scopes = session.send_request('scopes',
                                           arguments={
                                               'frameId': hit.frame_id
                                           }).wait_for_response()
        scopes = resp_scopes.body['scopes']
        assert len(scopes) > 0

        resp_variables = session.send_request(
            'variables',
            arguments={
                'variablesReference': scopes[0]['variablesReference']
            }).wait_for_response()
        variables = list(v for v in resp_variables.body['variables']
                         if v['name'] == 'a')
        assert len(variables) == 1
        assert variables[0] == {
            'type': 'int',
            'value': '1',
            'name': 'a',
            'evaluateName': "a"
        }

        resp_set_variable = session.send_request(
            'setVariable',
            arguments={
                'variablesReference': scopes[0]['variablesReference'],
                'name': 'a',
                'value': '1000'
            }).wait_for_response()
        assert resp_set_variable.body == ANY.dict_with({
            'type': 'int',
            'value': '1000'
        })

        session.send_request('continue').wait_for_response(freeze=False)

        assert session.read_json() == 1000

        session.wait_for_exit()
Example #6
0
def test_breakpoint_function(pyfile, run_as, start_method):

    @pyfile
    def code_to_debug():
        # NOTE: These tests verify break_into_debugger for launch
        # and attach cases. For attach this is always after wait_for_attach
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        breakpoint()
        print('break here')

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
        )
        session.start_debugging()
        hit = session.wait_for_thread_stopped()
        frames = hit.stacktrace.body['stackFrames']
        path = frames[0]['source']['path']
        assert path.endswith('code_to_debug.py') or path.endswith('<string>')
        assert frames[0]['line'] == 6

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Example #7
0
def test_attaching_by_pid(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        # import_and_enable_debugger()
        import time
        def do_something(i):
            time.sleep(0.1)
            print(i)
        for i in range(100):
            do_something(i)
    bp_line = 5
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
        )
        session.set_breakpoints(code_to_debug, [bp_line])
        session.start_debugging()
        hit = session.wait_for_thread_stopped()
        frames = hit.stacktrace.body['stackFrames']
        assert bp_line == frames[0]['line']

        # remove breakpoint and continue
        session.set_breakpoints(code_to_debug, [])
        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_next(Event('output', ANY.dict_with({'category': 'stdout'})))
        session.wait_for_exit()
Example #8
0
def test_exit_on_disconnect_for_launch(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        import os.path
        fp = os.join(os.path.dirname(os.path.abspath(__file__)), 'here.txt')
        # should not execute this
        with open(fp, 'w') as f:
            print('Should not continue after disconnect on launch', file=f)

    bp_line = 4
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            use_backchannel=True,
            expected_returncode=ANY.int,
        )
        session.set_breakpoints(code_to_debug, [bp_line])
        session.start_debugging()
        hit = session.wait_for_thread_stopped('breakpoint')
        frames = hit.stacktrace.body['stackFrames']
        assert frames[0]['line'] == bp_line
        session.send_request('disconnect').wait_for_response()
        session.wait_for_exit()
        fp = os.join(os.path.dirname(os.path.abspath(code_to_debug)),
                     'here.txt')
        assert not os.path.exists(fp)
Example #9
0
def test_wait_on_normal_exit_enabled(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        import backchannel
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        import ptvsd
        ptvsd.break_into_debugger()
        backchannel.write_json('done')

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            debug_options=['WaitOnNormalExit'],
            ignore_unobserved=[Event('continued')],
            use_backchannel=True,
        )
        session.start_debugging()

        session.wait_for_thread_stopped()
        session.send_request('continue').wait_for_response(freeze=False)

        session.expected_returncode = ANY.int
        assert session.read_json() == 'done'

        session.process.stdin.write(b' \r\n')
        session.wait_for_exit()

        decoded = u'\n'.join((x.decode('utf-8') if isinstance(x, bytes) else x)
                             for x in session.output_data['OUT'])

        assert u'Press' in decoded
Example #10
0
def test_success_exitcodes(pyfile, run_as, start_method, exit_code):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        import sys
        exit_code = eval(sys.argv[1])
        print('sys.exit(%r)' % (exit_code, ))
        sys.exit(exit_code)

    with DebugSession() as session:
        session.program_args = [repr(exit_code)]
        session.success_exitcodes = [3]
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            ignore_unobserved=[Event('continued')],
            expected_returncode=exit_code,
        )
        session.send_request('setExceptionBreakpoints', {
            'filters': ['uncaught']
        }).wait_for_response()
        session.start_debugging()

        if exit_code == 0:
            session.wait_for_thread_stopped(reason='exception')
            session.send_request('continue').wait_for_response(freeze=False)

        session.wait_for_exit()
Example #11
0
def test_continue_on_disconnect_for_attach(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        import backchannel
        backchannel.write_json('continued')

    bp_line = 4
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            ignore_unobserved=[Event('exited'),
                               Event('terminated')],
            use_backchannel=True,
        )
        session.set_breakpoints(code_to_debug, [bp_line])
        session.start_debugging()
        hit = session.wait_for_thread_stopped('breakpoint')
        frames = hit.stacktrace.body['stackFrames']
        assert frames[0]['line'] == bp_line
        session.send_request('disconnect').wait_for_response()
        session.wait_for_disconnect()
        assert 'continued' == session.read_json()
Example #12
0
def test_nodebug(pyfile, run_as):
    @pyfile
    def code_to_debug():
        # import_and_enable_debugger
        import backchannel
        backchannel.read_json()
        print('ok')

    with DebugSession() as session:
        session.no_debug = True
        session.initialize(target=(run_as, code_to_debug),
                           start_method='launch',
                           use_backchannel=True)
        session.set_breakpoints(code_to_debug, [3])
        session.start_debugging()

        session.write_json(None)

        # Breakpoint shouldn't be hit.
        session.wait_for_exit()

        session.expect_realized(
            Event('output',
                  ANY.dict_with({
                      'category': 'stdout',
                      'output': 'ok',
                  })))
Example #13
0
def test_with_tab_in_output(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        a = '\t'.join(('Hello', 'World'))
        print(a)
        # Break here so we are sure to get the output event.
        a = 1 # @bp1

    line_numbers = get_marked_line_numbers(code_to_debug)
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
        )

        session.set_breakpoints(code_to_debug, [line_numbers['bp1']])
        session.start_debugging()

        # Breakpoint at the end just to make sure we get all output events.
        session.wait_for_thread_stopped()
        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()

        output = session.all_occurrences_of(Event('output', ANY.dict_with({'category': 'stdout'})))
        output_str = ''.join(o.body['output'] for o in output)
        assert output_str.startswith('Hello\tWorld')
Example #14
0
def test_break_on_entry(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        import backchannel
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        backchannel.write_json('done')

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            debug_options=['StopOnEntry'],
            ignore_unobserved=[Event('continued')],
            use_backchannel=True,
        )
        session.start_debugging()

        thread_stopped, resp_stacktrace, tid, _ = session.wait_for_thread_stopped(
        )
        frames = resp_stacktrace.body['stackFrames']
        assert frames[0]['line'] == 1

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_termination()

        assert session.read_json() == 'done'

        session.wait_for_exit()
Example #15
0
def test_exit_normally_with_wait_on_abnormal_exit_enabled(
        pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        import backchannel
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        import ptvsd
        ptvsd.break_into_debugger()
        backchannel.write_json('done')

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            debug_options=['WaitOnAbnormalExit'],
            ignore_unobserved=[Event('continued')],
            use_backchannel=True,
        )
        session.start_debugging()

        session.wait_for_thread_stopped()
        session.send_request('continue').wait_for_response(freeze=False)

        session.wait_for_termination()

        assert session.read_json() == 'done'

        session.wait_for_exit()
Example #16
0
def test_vsc_exception_options_raise_with_except(pyfile, run_as, start_method, raised, uncaught):

    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()

        def raise_with_except():
            try:
                raise ArithmeticError('bad code')  # @exception_line
            except Exception:
                pass

        raise_with_except()

    line_numbers = get_marked_line_numbers(code_to_debug)
    ex_line = line_numbers['exception_line']
    filters = []
    filters += ['raised'] if raised == 'raisedOn' else []
    filters += ['uncaught'] if uncaught == 'uncaughtOn' else []
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            ignore_unobserved=[Event('continued')],
        )
        session.send_request('setExceptionBreakpoints', {
            'filters': filters
        }).wait_for_response()
        session.start_debugging()

        expected = ANY.dict_with({
            'exceptionId': ANY.such_that(lambda s: s.endswith('ArithmeticError')),
            'description': 'bad code',
            'breakMode': 'always' if raised == 'raisedOn' else 'unhandled',
            'details': ANY.dict_with({
                'typeName': ANY.such_that(lambda s: s.endswith('ArithmeticError')),
                'message': 'bad code',
                'source': Path(code_to_debug),
            }),
        })

        if raised == 'raisedOn':
            hit = session.wait_for_thread_stopped(reason='exception')
            frames = hit.stacktrace.body['stackFrames']
            assert ex_line == frames[0]['line']

            resp_exc_info = session.send_request('exceptionInfo', {
                'threadId': hit.thread_id
            }).wait_for_response()

            assert resp_exc_info.body == expected
            session.send_request('continue').wait_for_response(freeze=False)

        # uncaught should not 'stop' matter since the exception is caught

        session.wait_for_exit()
Example #17
0
def test_argv_quoting(pyfile, run_as, start_method):
    @pyfile
    def args():
        # import_and_enable_debugger
        args = [  # noqa
            r'regular',
            r'',
            r'with spaces'
            r'"quoted"',
            r'" quote at start',
            r'quote at end "',
            r'quote in " the middle',
            r'quotes "in the" middle',
            r'\path with\spaces',
            r'\path\with\terminal\backslash' + '\\',
            r'backslash \" before quote',
        ]

    @pyfile
    def parent():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()

        import sys
        import subprocess
        from args import args
        child = sys.argv[1]
        subprocess.check_call([sys.executable] + [child] + args)

    @pyfile
    def child():
        # import_and_enable_debugger
        import backchannel
        import sys

        from args import args as expected_args
        backchannel.write_json(expected_args)

        actual_args = sys.argv[1:]
        backchannel.write_json(actual_args)

    with DebugSession() as session:
        session.initialize(
            target=(run_as, parent),
            start_method=start_method,
            program_args=[child],
            use_backchannel=True,
            ignore_unobserved=[Event('continued')],
        )

        session.start_debugging()

        expected_args = session.read_json()
        actual_args = session.read_json()
        assert expected_args == actual_args

        session.wait_for_exit()
Example #18
0
def test_conditional_breakpoint(pyfile, run_as, start_method, condition_key):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        for i in range(0, 10):
            print(i)

    expected = {
        'condition_var': ('condition', 'i==5', '5', 1),
        'hitCondition_#': ('hitCondition', '5', '4', 1),
        'hitCondition_eq': ('hitCondition', '==5', '4', 1),
        'hitCondition_gt': ('hitCondition', '>5', '5', 5),
        'hitCondition_ge': ('hitCondition', '>=5', '4', 6),
        'hitCondition_lt': ('hitCondition', '<5', '0', 4),
        'hitCondition_le': ('hitCondition', '<=5', '0', 5),
        'hitCondition_mod': ('hitCondition', '%3', '2', 3),
    }
    condition_type, condition, value, hits = expected[condition_key]

    bp_line = 4
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            ignore_unobserved=[Event('continued')],
        )
        session.send_request('setBreakpoints', arguments={
            'source': {'path': code_to_debug},
            'breakpoints': [{'line': bp_line, condition_type: condition}],
        }).wait_for_response()
        session.start_debugging()
        hit = session.wait_for_thread_stopped()
        frames = hit.stacktrace.body['stackFrames']
        assert bp_line == frames[0]['line']

        resp_scopes = session.send_request('scopes', arguments={
            'frameId': hit.frame_id
        }).wait_for_response()
        scopes = resp_scopes.body['scopes']
        assert len(scopes) > 0

        resp_variables = session.send_request('variables', arguments={
            'variablesReference': scopes[0]['variablesReference']
        }).wait_for_response()
        variables = list(v for v in resp_variables.body['variables']
                         if v['name'] == 'i')
        assert variables == [
            ANY.dict_with({'name': 'i', 'type': 'int', 'value': value, 'evaluateName': 'i'})
        ]

        session.send_request('continue').wait_for_response(freeze=False)
        for i in range(1, hits):
            session.wait_for_thread_stopped()
            session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Example #19
0
def test_flask_template_exception_no_multiproc(start_method):
    with DebugSession() as session:
        _initialize_flask_session_no_multiproc(session, start_method)

        session.send_request('setExceptionBreakpoints', arguments={
            'filters': ['raised', 'uncaught'],
        }).wait_for_response()

        session.start_debugging()

        # wait for Flask web server to start
        wait_for_connection(FLASK_PORT)
        base_link = FLASK_LINK
        part = 'badtemplate'
        link = base_link + part if base_link.endswith('/') else ('/' + part)
        web_request = get_web_content(link, {})

        hit = session.wait_for_thread_stopped()
        frames = hit.stacktrace.body['stackFrames']
        assert frames[0] == ANY.dict_with({
            'id': ANY.dap_id,
            'name': 'template' if sys.version_info[0] >= 3 else 'Jinja2 TemplateSyntaxError',
            'source': ANY.dict_with({
                'sourceReference': ANY.dap_id,
                'path': Path(FLASK1_BAD_TEMPLATE),
            }),
            'line': 8,
            'column': 1,
        })

        resp_exception_info = session.send_request(
            'exceptionInfo',
            arguments={'threadId': hit.thread_id, }
        ).wait_for_response()
        exception = resp_exception_info.body
        assert exception == ANY.dict_with({
            'exceptionId': ANY.such_that(lambda s: s.endswith('TemplateSyntaxError')),
            'breakMode': 'always',
            'description': ANY.such_that(lambda s: s.find('doesnotexist') > -1),
            'details': ANY.dict_with({
                'message': ANY.such_that(lambda s: s.find('doesnotexist') > -1),
                'typeName': ANY.such_that(lambda s: s.endswith('TemplateSyntaxError')),
            })
        })

        session.send_request('continue').wait_for_response(freeze=False)

        # ignore response for exception tests
        web_request.wait_for_response()

        # shutdown to web server
        link = base_link + 'exit' if base_link.endswith('/') else '/exit'
        get_web_content(link).wait_for_response()

        session.wait_for_exit()
Example #20
0
def test_completions_scope(pyfile, bp_line, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        class SomeClass():
            def __init__(self, someVar):
                self.some_var = someVar
            def do_someting(self):
                someVariable = self.some_var
                return someVariable
        def someFunction(someVar):
            someVariable = someVar
            return SomeClass(someVariable).do_someting()
        someFunction('value')
        print('done')

    expected = expected_at_line[bp_line]

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            ignore_unobserved=[Event('stopped'), Event('continued')],
        )
        session.set_breakpoints(code_to_debug, [bp_line])
        session.start_debugging()

        thread_stopped = session.wait_for_next(Event('stopped', ANY.dict_with({'reason': 'breakpoint'})))
        assert thread_stopped.body['threadId'] is not None
        tid = thread_stopped.body['threadId']

        resp_stacktrace = session.send_request('stackTrace', arguments={
            'threadId': tid,
        }).wait_for_response()
        assert resp_stacktrace.body['totalFrames'] > 0
        frames = resp_stacktrace.body['stackFrames']
        assert len(frames) > 0

        fid = frames[0]['id']
        resp_completions = session.send_request('completions', arguments={
            'text': 'some',
            'frameId': fid,
            'column': 5,
        }).wait_for_response()
        targets = resp_completions.body['targets']

        session.send_request('continue').wait_for_response(freeze=False)

        targets.sort(key=lambda t: t['label'])
        expected.sort(key=lambda t: t['label'])
        assert targets == expected

        session.wait_for_exit()
Example #21
0
def test_log_point(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        a = 10
        for i in range(1, a):
            print('value: %d' % i)
        # Break at end too so that we're sure we get all output
        # events before the break.
        a = 10

    bp_line = 5
    end_bp_line = 8
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
        )
        session.send_request('setBreakpoints',
                             arguments={
                                 'source': {
                                     'path': code_to_debug
                                 },
                                 'breakpoints': [{
                                     'line': bp_line,
                                     'logMessage': 'log: {a + i}'
                                 }, {
                                     'line': end_bp_line
                                 }],
                             }).wait_for_response()
        session.start_debugging()

        # Breakpoint at the end just to make sure we get all output events.
        hit = session.wait_for_thread_stopped()
        frames = hit.stacktrace.body['stackFrames']
        assert end_bp_line == frames[0]['line']

        session.send_request('continue').wait_for_response(freeze=False)

        session.wait_for_exit()
        assert session.get_stderr_as_string() == b''

        output = session.all_occurrences_of(
            Event('output', ANY.dict_with({'category': 'stdout'})))
        output_str = ''.join(o.body['output'] for o in output)
        logged = sorted(
            int(i) for i in re.findall(r"log:\s([0-9]*)", output_str))
        values = sorted(
            int(i) for i in re.findall(r"value:\s([0-9]*)", output_str))

        assert logged == list(range(11, 20))
        assert values == list(range(1, 10))
Example #22
0
def test_debug_this_thread(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()

        import platform
        import ptvsd
        import threading

        def foo(x):
            ptvsd.debug_this_thread()
            event.set()  #@bp
            return 0

        event = threading.Event()

        if platform.system() == 'Windows':
            from ctypes import CFUNCTYPE, c_void_p, c_size_t, c_uint32, windll
            thread_func_p = CFUNCTYPE(c_uint32, c_void_p)
            thread_func = thread_func_p(
                foo)  # must hold a reference to wrapper during the call
            assert windll.kernel32.CreateThread(c_void_p(0), c_size_t(0),
                                                thread_func, c_void_p(0),
                                                c_uint32(0), c_void_p(0))
        elif platform.system() == 'Linux' or platform.system() == 'Darwin':
            from ctypes import CDLL, CFUNCTYPE, byref, c_void_p, c_ulong
            from ctypes.util import find_library
            libpthread = CDLL(find_library('libpthread'))
            thread_func_p = CFUNCTYPE(c_void_p, c_void_p)
            thread_func = thread_func_p(
                foo)  # must hold a reference to wrapper during the call
            assert not libpthread.pthread_create(byref(
                c_ulong(0)), c_void_p(0), thread_func, c_void_p(0))
        else:
            assert False

        event.wait()

    line_numbers = get_marked_line_numbers(code_to_debug)

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            ignore_unobserved=[Event('continued')],
        )
        session.set_breakpoints(code_to_debug, [line_numbers['bp']])
        session.start_debugging()

        session.wait_for_thread_stopped()
        session.send_request('continue').wait_for_response()
        session.wait_for_exit()
Example #23
0
def test_exceptions_and_exclude_rules(pyfile, run_as, start_method, scenario,
                                      exception_type):

    if exception_type == 'RuntimeError':

        @pyfile
        def code_to_debug():
            from dbgimporter import import_and_enable_debugger
            import_and_enable_debugger()
            raise RuntimeError('unhandled error')  # @raise_line

    elif exception_type == 'SysExit':

        @pyfile
        def code_to_debug():
            from dbgimporter import import_and_enable_debugger
            import sys
            import_and_enable_debugger()
            sys.exit(1)  # @raise_line

    else:
        raise AssertionError('Unexpected exception_type: %s' %
                             (exception_type, ))

    if scenario == 'exclude_by_name':
        rules = [{
            'path': '**/' + os.path.basename(code_to_debug),
            'include': False
        }]
    elif scenario == 'exclude_by_dir':
        rules = [{'path': os.path.dirname(code_to_debug), 'include': False}]
    else:
        raise AssertionError('Unexpected scenario: %s' % (scenario, ))

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            rules=rules,
        )
        # TODO: The process returncode doesn't match the one returned from the DAP.
        # See: https://github.com/Microsoft/ptvsd/issues/1278
        session.expected_returncode = ANY.int
        filters = ['raised', 'uncaught']

        session.send_request('setExceptionBreakpoints', {
            'filters': filters
        }).wait_for_response()
        session.start_debugging()

        # No exceptions should be seen.
        session.wait_for_exit()
Example #24
0
def test_with_no_output(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        # Do nothing, and check if there is any output

    with DebugSession() as session:
        session.initialize(target=(run_as, code_to_debug), start_method=start_method)
        session.start_debugging()
        session.wait_for_exit()
        assert b'' == session.get_stdout_as_string()
        assert b'' == session.get_stderr_as_string()
Example #25
0
def test_completions_cases(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        a = 1
        b = {"one": 1, "two": 2}
        c = 3
        print([a, b, c])

    bp_line = 6
    bp_file = code_to_debug

    with DebugSession() as session:
        session.initialize(
            target=(run_as, bp_file),
            start_method=start_method,
            ignore_unobserved=[Event('continued')],
        )
        session.set_breakpoints(bp_file, [bp_line])
        session.start_debugging()
        hit = session.wait_for_thread_stopped()

        response = session.send_request('completions', arguments={
            'frameId': hit.frame_id,
            'text': 'b.',
            'column': 3,
        }).wait_for_response()

        labels = set(target['label'] for target in response.body['targets'])
        assert labels.issuperset(['get', 'items', 'keys', 'setdefault', 'update', 'values'])

        response = session.send_request('completions', arguments={
            'frameId': hit.frame_id,
            'text': 'x = b.setdefault',
            'column': 13,
        }).wait_for_response()

        assert response.body['targets'] == [
            {'label': 'setdefault', 'length': 6, 'start': 6, 'type': 'function'}]

        response = session.send_request('completions', arguments={
            'frameId': hit.frame_id,
            'text': 'not_there',
            'column': 10,
        }).wait_for_response()

        assert not response.body['targets']

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Example #26
0
def test_justmycode_frames(pyfile, run_as, start_method, jmc):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        print('break here')  #@bp

    line_numbers = get_marked_line_numbers(code_to_debug)
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            ignore_unobserved=[Event('continued')],
            debug_options=[] if jmc == 'jmcOn' else ['DebugStdLib'])

        bp_line = line_numbers['bp']

        actual_bps = session.set_breakpoints(code_to_debug, [bp_line])
        actual_bps = [bp['line'] for bp in actual_bps]
        session.start_debugging()

        hit = session.wait_for_thread_stopped()
        frames = hit.stacktrace.body['stackFrames']
        assert frames[0] == ANY.dict_with({
            'line':
            bp_line,
            'source':
            ANY.dict_with({'path': Path(code_to_debug)})
        })

        if jmc == 'jmcOn':
            assert len(frames) == 1
            session.send_request('stepIn', {
                'threadId': hit.thread_id
            }).wait_for_response()
            # 'step' should terminate the debuggee
        else:
            assert len(frames) >= 1
            session.send_request('stepIn', {
                'threadId': hit.thread_id
            }).wait_for_response()

            # 'step' should enter stdlib
            hit2 = session.wait_for_thread_stopped()
            frames2 = hit2.stacktrace.body['stackFrames']
            assert frames2[0]['source']['path'] != Path(code_to_debug)

            # 'continue' should terminate the debuggee
            session.send_request('continue').wait_for_response(freeze=False)

        session.wait_for_exit()
Example #27
0
def test_deep_stacks(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()

        def deep_stack(level):
            if level <= 0:
                print('done')  #@bp
                return level
            deep_stack(level - 1)

        deep_stack(100)

    line_numbers = get_marked_line_numbers(code_to_debug)
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
        )

        bp_line = line_numbers['bp']

        actual_bps = session.set_breakpoints(code_to_debug, [bp_line])
        actual_bps = [bp['line'] for bp in actual_bps]
        session.start_debugging()

        hit = session.wait_for_thread_stopped()
        full_frames = hit.stacktrace.body['stackFrames']
        assert len(full_frames) > 100

        # Construct stack from parts
        frames = []
        start = 0
        for _ in range(5):
            resp_stacktrace = session.send_request('stackTrace',
                                                   arguments={
                                                       'threadId':
                                                       hit.thread_id,
                                                       'startFrame': start,
                                                       'levels': 25
                                                   }).wait_for_response()
            assert resp_stacktrace.body['totalFrames'] > 0
            frames += resp_stacktrace.body['stackFrames']
            start = len(frames)

        assert full_frames == frames

        session.send_request('continue').wait_for_response()
        session.wait_for_exit()
Example #28
0
def test_log_api(pyfile, tmpdir, run_as):
    @pyfile
    def code_to_debug():
        import sys
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger(log_dir=str(sys.argv[1]))

    with DebugSession() as session:
        with check_logs(tmpdir, session):
            session.program_args += [str(tmpdir)]
            session.initialize(target=(run_as, code_to_debug),
                               start_method='attach_socket_import')
            session.start_debugging()
            session.wait_for_exit()
Example #29
0
def test_autokill(pyfile, run_as, start_method):
    @pyfile
    def child():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        while True:
            pass

    @pyfile
    def parent():
        import backchannel
        import os
        import subprocess
        import sys
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        argv = [sys.executable, sys.argv[1]]
        env = os.environ.copy()
        subprocess.Popen(argv,
                         env=env,
                         stdin=subprocess.PIPE,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
        backchannel.read_json()

    with DebugSession() as parent_session:
        parent_session.program_args += [child]
        parent_session.initialize(multiprocess=True,
                                  target=(run_as, parent),
                                  start_method=start_method,
                                  use_backchannel=True)
        parent_session.start_debugging()

        with parent_session.connect_to_next_child_session() as child_session:
            child_session.start_debugging()

            if parent_session.start_method == 'launch':
                # In launch scenario, terminate the parent process by disconnecting from it.
                parent_session.expected_returncode = ANY
                disconnect = parent_session.send_request('disconnect', {})
                parent_session.wait_for_next(Response(disconnect))
            else:
                # In attach scenario, just let the parent process run to completion.
                parent_session.expected_returncode = 0
                parent_session.write_json(None)

            child_session.wait_for_termination()
            parent_session.wait_for_exit()
Example #30
0
def test_with_tab_in_output(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        print('Hello\tWorld')

    with DebugSession() as session:
        session.initialize(target=(run_as, code_to_debug),
                           start_method=start_method)
        session.start_debugging()
        session.wait_for_exit()
        output = session.all_occurrences_of(
            Event('output', ANY.dict_with({'category': 'stdout'})))
        output_str = ''.join(o.body['output'] for o in output)
        assert output_str.startswith('Hello\tWorld')