mirror of
https://github.com/microsoft/debugpy.git
synced 2025-12-23 08:48:12 +00:00
This reverts commit bd390322a8.
Fixes #633
Fixes #618
This commit is contained in:
parent
4ab7920628
commit
6017f03022
3 changed files with 51 additions and 43 deletions
|
|
@ -5,7 +5,9 @@ import threading
|
|||
from ptvsd import wrapper
|
||||
from ptvsd.socket import (
|
||||
close_socket, create_server, create_client, connect, Address)
|
||||
from .exit_handlers import ExitHandlers, UnsupportedSignalError
|
||||
from .exit_handlers import (
|
||||
ExitHandlers, UnsupportedSignalError,
|
||||
kill_current_proc)
|
||||
from .session import PyDevdDebugSession
|
||||
from ._util import (
|
||||
ClosedError, NotRunningError, ignore_errors, debug, lock_wait)
|
||||
|
|
@ -82,7 +84,7 @@ class DaemonBase(object):
|
|||
self._wait_for_user = wait_for_user
|
||||
self._killonclose = killonclose
|
||||
|
||||
self._exiting = False
|
||||
self._exiting_via_atexit_handler = False
|
||||
|
||||
self._exithandlers = ExitHandlers()
|
||||
if addhandlers:
|
||||
|
|
@ -282,29 +284,42 @@ class DaemonBase(object):
|
|||
with ignore_errors():
|
||||
self._stop()
|
||||
|
||||
def _kill_after_single_session(self):
|
||||
if self._killonclose:
|
||||
if not self._exiting:
|
||||
# Ensure the proc is exiting before closing socket.
|
||||
# Note that this will trigger the atexit handler.
|
||||
self._exiting = True
|
||||
sys.exit(0)
|
||||
else:
|
||||
try:
|
||||
self.close()
|
||||
except DaemonClosedError:
|
||||
pass
|
||||
|
||||
def _handle_session_disconnecting(self, session):
|
||||
debug('handling disconnecting session')
|
||||
if self._singlesession:
|
||||
self._kill_after_single_session()
|
||||
if self._killonclose:
|
||||
with self._lock:
|
||||
if not self._exiting_via_atexit_handler:
|
||||
# Ensure the proc is exiting before closing
|
||||
# socket. Note that we kill the proc instead
|
||||
# of calling sys.exit(0).
|
||||
# Note that this will trigger either the atexit
|
||||
# handler or the signal handler.
|
||||
kill_current_proc()
|
||||
else:
|
||||
try:
|
||||
self.close()
|
||||
except DaemonClosedError:
|
||||
pass
|
||||
|
||||
def _handle_session_closing(self, session):
|
||||
debug('handling closing session')
|
||||
|
||||
if self._singlesession:
|
||||
self._kill_after_single_session()
|
||||
if self._killonclose:
|
||||
with self._lock:
|
||||
if not self._exiting_via_atexit_handler:
|
||||
# Ensure the proc is exiting before closing
|
||||
# socket. Note that we kill the proc instead
|
||||
# of calling sys.exit(0).
|
||||
# Note that this will trigger either the atexit
|
||||
# handler or the signal handler.
|
||||
kill_current_proc()
|
||||
else:
|
||||
try:
|
||||
self.close()
|
||||
except DaemonClosedError:
|
||||
pass
|
||||
else:
|
||||
self._finish_session()
|
||||
|
||||
|
|
@ -397,7 +412,8 @@ class DaemonBase(object):
|
|||
|
||||
def _handle_atexit(self):
|
||||
debug('handling atexit')
|
||||
self._exiting = True
|
||||
with self._lock:
|
||||
self._exiting_via_atexit_handler = True
|
||||
session = self.session
|
||||
|
||||
if session is not None:
|
||||
|
|
@ -428,8 +444,7 @@ class DaemonBase(object):
|
|||
self.close()
|
||||
except DaemonClosedError:
|
||||
pass
|
||||
if not self._exiting:
|
||||
self._exiting = True
|
||||
if not self._exiting_via_atexit_handler:
|
||||
sys.exit(0)
|
||||
|
||||
# methods for subclasses to override
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ from ptvsd import _util
|
|||
import ptvsd.ipcjson as ipcjson # noqa
|
||||
import ptvsd.futures as futures # noqa
|
||||
import ptvsd.untangle as untangle # noqa
|
||||
from ptvsd.exit_handlers import kill_current_proc
|
||||
from ptvsd.pathutils import PathUnNormcase # noqa
|
||||
from ptvsd.safe_repr import SafeRepr # noqa
|
||||
from ptvsd.version import __version__ # noqa
|
||||
|
|
@ -1008,9 +1007,6 @@ class VSCLifecycleMsgProcessor(VSCodeMessageProcessorBase):
|
|||
|
||||
self._stopped = False
|
||||
|
||||
# This is overridden in tests.
|
||||
self._kill_current_proc = kill_current_proc
|
||||
|
||||
# adapter state
|
||||
self.start_reason = None
|
||||
self.debug_options = {}
|
||||
|
|
@ -1108,30 +1104,28 @@ class VSCLifecycleMsgProcessor(VSCodeMessageProcessorBase):
|
|||
|
||||
status = {'sent': False}
|
||||
|
||||
def finish_disconnect():
|
||||
def disconnect_response():
|
||||
if status['sent']:
|
||||
return
|
||||
self.send_response(request)
|
||||
status['sent'] = True
|
||||
|
||||
if self.start_reason == 'launch':
|
||||
if not self.closed:
|
||||
# Closing the socket causes pydevd to resume all
|
||||
# threads, so just terminate the process altogether.
|
||||
# TODO: The wrapper should not be responsible for
|
||||
# managing the process (e.g. killing it).
|
||||
self._kill_current_proc()
|
||||
|
||||
self._set_disconnected()
|
||||
if self.start_reason == 'attach':
|
||||
if not self._debuggerstopped:
|
||||
self._handle_detach()
|
||||
self._notify_disconnecting(
|
||||
pre_socket_close=finish_disconnect,
|
||||
pre_socket_close=disconnect_response,
|
||||
)
|
||||
# The callback might never get called in notify_disconnecting,
|
||||
# so we call it again here to make sure it is called.
|
||||
finish_disconnect()
|
||||
disconnect_response()
|
||||
|
||||
self._set_disconnected()
|
||||
|
||||
if self.start_reason == 'attach':
|
||||
if not self._debuggerstopped:
|
||||
self._handle_detach()
|
||||
# TODO: We should be able drop the "launch" branch.
|
||||
elif self.start_reason == 'launch':
|
||||
if not self.closed:
|
||||
# Closing the socket causes pydevd to resume all threads,
|
||||
# so just terminate the process altogether.
|
||||
sys.exit(0)
|
||||
|
||||
# internal methods
|
||||
|
||||
|
|
|
|||
|
|
@ -30,8 +30,7 @@ class PTVSD(ptvsd.daemon.Daemon):
|
|||
singlesession=singlesession,
|
||||
)
|
||||
self.start()
|
||||
session = self.start_session(client, 'ptvsd.Server')
|
||||
session._msgprocessor._kill_current_proc = (lambda: None)
|
||||
self.start_session(client, 'ptvsd.Server')
|
||||
self.server = server
|
||||
return self
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue