Revert "Use sys.exit() instead of os.kill(). (#538)" (#634)

This reverts commit bd390322a8.
Fixes #633
Fixes #618
This commit is contained in:
Don Jayamanne 2018-07-11 12:58:49 -07:00 committed by GitHub
parent 4ab7920628
commit 6017f03022
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 43 deletions

View file

@ -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

View file

@ -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

View file

@ -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