Example #1
0
def test_subprocess(debug_session, pyfile, start_method, run_as):
    @pyfile
    def child():
        import sys
        import backchannel
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        backchannel.write_json(sys.argv)

    @pyfile
    def parent():
        import os
        import subprocess
        import sys
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        argv = [sys.executable, sys.argv[1], '--arg1', '--arg2', '--arg3']
        env = os.environ.copy()
        process = subprocess.Popen(argv, env=env, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        process.wait()

    debug_session.program_args += [child]
    debug_session.initialize(multiprocess=True, target=(run_as, parent), start_method=start_method, use_backchannel=True)
    debug_session.start_debugging()

    root_start_request, = debug_session.all_occurrences_of(Request('launch') | Request('attach'))
    root_process, = debug_session.all_occurrences_of(Event('process'))
    root_pid = int(root_process.body['systemProcessId'])

    child_subprocess = debug_session.wait_for_next(Event('ptvsd_subprocess'))
    assert child_subprocess == Event('ptvsd_subprocess', {
        'rootProcessId': root_pid,
        'parentProcessId': root_pid,
        'processId': ANY.int,
        'port': ANY.int,
        'rootStartRequest': {
            'seq': ANY.int,
            'type': 'request',
            'command': root_start_request.command,
            'arguments': root_start_request.arguments,
        }
    })
    child_pid = child_subprocess.body['processId']
    child_port = child_subprocess.body['port']
    debug_session.proceed()

    child_session = DebugSession(start_method=START_METHOD_CMDLINE, ptvsd_port=child_port, pid=child_pid)
    child_session.ignore_unobserved = debug_session.ignore_unobserved
    child_session.connect()
    child_session.handshake()
    child_session.start_debugging()

    child_argv = debug_session.read_json()
    assert child_argv == [child, '--arg1', '--arg2', '--arg3']

    child_session.wait_for_exit()
    debug_session.wait_for_exit()
Example #2
0
def test_autokill(debug_session, pyfile, start_method, run_as):
    @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()

    debug_session.program_args += [child]
    debug_session.initialize(multiprocess=True, target=(run_as, parent), start_method=start_method, use_backchannel=True)
    debug_session.start_debugging()

    child_subprocess = debug_session.wait_for_next(Event('ptvsd_subprocess'))
    child_pid = child_subprocess.body['processId']
    child_port = child_subprocess.body['port']

    debug_session.proceed()

    child_session = DebugSession(start_method=START_METHOD_CMDLINE, ptvsd_port=child_port, pid=child_pid)
    child_session.expected_returncode = ANY
    child_session.connect()
    child_session.handshake()
    child_session.start_debugging()

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

    debug_session.wait_for_exit()
    child_session.wait_for_exit()