Skip to content
This repository has been archived by the owner on Aug 2, 2023. It is now read-only.

Commit

Permalink
Fix #355: Add 'remote launch' - launch a program for remote debugging…
Browse files Browse the repository at this point in the history
… but continue running the user code (#769)

* Fix #355: Add 'remote launch' - launch a program for remote debugging but continue running the user code

Add --wait command line argument, and don't block code execution if it is not specified.

* Add copyright headers.
  • Loading branch information
int19h authored and karthiknadig committed Aug 28, 2018
1 parent 2e78687 commit f453ed1
Show file tree
Hide file tree
Showing 14 changed files with 107 additions and 4 deletions.
6 changes: 4 additions & 2 deletions ptvsd/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def _group_args(argv):
if nextarg is not None:
supported.append(nextarg)
skip += 1
elif arg in ('--single-session',):
elif arg in ('--single-session', '--wait'):
supported.append(arg)
elif not arg.startswith('-'):
supported.append(arg)
Expand Down Expand Up @@ -166,6 +166,8 @@ def _parse_args(prog, argv):
target.add_argument('filename', nargs='?')

parser.add_argument('--single-session', action='store_true')
parser.add_argument('--wait', action='store_true')

parser.add_argument('-V', '--version', action='version')
parser.version = __version__

Expand Down Expand Up @@ -208,4 +210,4 @@ def main(addr, name, kind, extra=(), nodebug=False, **kwargs):
if __name__ == '__main__':
args, extra = parse_args()
main(args.address, args.name, args.kind, extra, nodebug=args.nodebug,
singlesession=args.single_session)
singlesession=args.single_session, wait=args.wait)
15 changes: 15 additions & 0 deletions ptvsd/_local.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE in the project root
# for license information.

import sys
import time

import pydevd
from _pydevd_bundle.pydevd_comm import get_global_debugger

from ptvsd.pydevd_hooks import install
from ptvsd.runner import run as no_debug_runner
from ptvsd.socket import Address
from ptvsd._util import new_hidden_thread


PYDEVD_DEFAULTS = {
Expand All @@ -24,6 +31,14 @@ def _set_pydevd_defaults(pydevd_args):
# high-level functions

def debug_main(address, name, kind, *extra, **kwargs):
if not kwargs.pop('wait', False) and address.isserver:
def unblock_debugger():
debugger = get_global_debugger()
while debugger is None:
time.sleep(0.1)
debugger = get_global_debugger()
debugger.ready_to_run = True
new_hidden_thread('ptvsd.unblock_debugger', unblock_debugger).start()
if kind == 'module':
run_module(address, name, *extra, **kwargs)
else:
Expand Down
4 changes: 4 additions & 0 deletions ptvsd/_remote.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE in the project root
# for license information.

import pydevd
import time

Expand Down
4 changes: 4 additions & 0 deletions ptvsd/_util.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE in the project root
# for license information.

from __future__ import print_function

import contextlib
Expand Down
4 changes: 4 additions & 0 deletions ptvsd/daemon.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE in the project root
# for license information.

import contextlib
import sys
import threading
Expand Down
4 changes: 4 additions & 0 deletions ptvsd/exit_handlers.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE in the project root
# for license information.

import atexit
import os
import platform
Expand Down
4 changes: 4 additions & 0 deletions ptvsd/pydevd_hooks.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE in the project root
# for license information.

import sys

from _pydevd_bundle import pydevd_comm
Expand Down
4 changes: 4 additions & 0 deletions ptvsd/session.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE in the project root
# for license information.

from .socket import is_socket, close_socket
from .wrapper import VSCodeMessageProcessor
from ._util import TimeoutError, ClosedError, Closeable, Startable, debug
Expand Down
4 changes: 4 additions & 0 deletions ptvsd/socket.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE in the project root
# for license information.

from __future__ import absolute_import

from collections import namedtuple
Expand Down
2 changes: 2 additions & 0 deletions tests/helpers/debugadapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ def _start_as(cls,
argv = []
if server:
argv += ['--server']
if kwargs.pop('wait', True):
argv += ['--wait']
if kind == 'script':
argv += [name]
elif kind == 'module':
Expand Down
9 changes: 8 additions & 1 deletion tests/helpers/debugclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,12 @@ def start(*args, **kwargs):
if wait_for_connect:
wait_for_connect()
else:
wait_for_socket_server(addr)
try:
wait_for_socket_server(addr)
except Exception:
# If we fail to connect, print out the adapter output.
self._adapter.VERBOSE = True
raise
self._attach(addr, **kwargs)

def _attach(self, addr, **kwargs):
Expand Down Expand Up @@ -243,6 +248,8 @@ def launch_script(self, filename, *argv, **kwargs):
] + list(argv)
if kwargs.pop('nodebug', False):
argv.insert(0, '--nodebug')
if kwargs.pop('wait', True):
argv.insert(0, '--wait')
self._launch(argv, **kwargs)
return self._adapter, self._session

Expand Down
9 changes: 8 additions & 1 deletion tests/helpers/debugsession.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,12 +279,19 @@ def _close(self):
self._check_handlers()

def _listen(self):
eof = None
try:
for msg in self._conn.iter_messages():
if self.VERBOSE:
print(' ->', msg)
self._receive_message(msg)
except EOFError:
except EOFError as ex:
# Handle EOF outside of except to avoid unnecessary chaining.
eof = ex
if eof:
remainder = getattr(eof, 'remainder', b'')
if remainder:
self._receive_message(remainder)
try:
self.close()
except ClosedError:
Expand Down
41 changes: 41 additions & 0 deletions tests/ptvsd/test___main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def test_module(self):
'address': Address.as_server(None, 8888),
'nodebug': False,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -39,6 +40,7 @@ def test_module_server(self):
'address': Address.as_server('10.0.1.1', 8888),
'nodebug': False,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -56,6 +58,7 @@ def test_module_nodebug(self):
'address': Address.as_client(None, 8888),
'nodebug': True,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -72,6 +75,7 @@ def test_script(self):
'address': Address.as_server(None, 8888),
'nodebug': False,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -89,6 +93,7 @@ def test_script_server(self):
'address': Address.as_server('10.0.1.1', 8888),
'nodebug': False,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -106,6 +111,7 @@ def test_script_nodebug(self):
'address': Address.as_client(None, 8888),
'nodebug': True,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -123,6 +129,7 @@ def test_remote(self):
'address': Address.as_client('1.2.3.4', 8888),
'nodebug': False,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -140,6 +147,7 @@ def test_remote_localhost(self):
'address': Address.as_client('localhost', 8888),
'nodebug': False,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -158,6 +166,7 @@ def test_remote_nodebug(self):
'address': Address.as_client('1.2.3.4', 8888),
'nodebug': True,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -175,6 +184,7 @@ def test_remote_single_session(self):
'address': Address.as_server('localhost', 8888),
'nodebug': False,
'single_session': True,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -193,6 +203,26 @@ def test_local_single_session(self):
'address': Address.as_server('1.2.3.4', 8888),
'nodebug': False,
'single_session': True,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

def test_remote_wait(self):
args, extra = parse_args([
'eggs',
'--host', '1.2.3.4',
'--port', '8888',
'--wait',
'spam.py',
])

self.assertEqual(vars(args), {
'kind': 'script',
'name': 'spam.py',
'address': Address.as_client('1.2.3.4', 8888),
'nodebug': False,
'single_session': False,
'wait': True,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -218,6 +248,7 @@ def test_extra(self):
'address': Address.as_server(None, 8888),
'nodebug': False,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, [
'--DEBUG',
Expand Down Expand Up @@ -254,6 +285,7 @@ def test_extra_nodebug(self):
'address': Address.as_client(None, 8888),
'nodebug': True,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, [
'--DEBUG',
Expand Down Expand Up @@ -281,6 +313,7 @@ def test_empty_host(self):
'address': Address.as_server('', 8888),
'nodebug': False,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand Down Expand Up @@ -308,6 +341,7 @@ def test_backward_compatibility_host(self):
'address': Address.as_client('1.2.3.4', 8888),
'nodebug': False,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -326,6 +360,7 @@ def test_backward_compatibility_host_nodebug(self):
'address': Address.as_client('1.2.3.4', 8888),
'nodebug': True,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -343,6 +378,7 @@ def test_backward_compatibility_module(self):
'address': Address.as_server(None, 8888),
'nodebug': False,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -361,6 +397,7 @@ def test_backward_compatibility_module_nodebug(self):
'address': Address.as_client(None, 8888),
'nodebug': True,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -377,6 +414,7 @@ def test_backward_compatibility_script(self):
'address': Address.as_server(None, 8888),
'nodebug': False,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -394,6 +432,7 @@ def test_backward_compatibility_script_nodebug(self):
'address': Address.as_client(None, 8888),
'nodebug': True,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, self.EXPECTED_EXTRA)

Expand All @@ -411,6 +450,7 @@ def test_pseudo_backward_compatibility(self):
'address': Address.as_server(None, 8888),
'nodebug': False,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, ['--module'] + self.EXPECTED_EXTRA)

Expand All @@ -429,5 +469,6 @@ def test_pseudo_backward_compatibility_nodebug(self):
'address': Address.as_client(None, 8888),
'nodebug': True,
'single_session': False,
'wait': False,
})
self.assertEqual(extra, ['--module'] + self.EXPECTED_EXTRA)
1 change: 1 addition & 0 deletions tests/system_tests/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ def connect(addr, wait=None, closeonly=False):
self.addCleanup(lambda: os.close(wpipe))
proc = Proc.start_python_module('ptvsd', [
'--server',
'--wait',
'--port', '5678',
'--file', filename,
], env={
Expand Down

0 comments on commit f453ed1

Please sign in to comment.