def enable_attach(secret, address=('0.0.0.0', ptvsd.DEFAULT_PORT), certfile=None, keyfile=None, redirect_output=True): if not ssl and (certfile or keyfile): raise ValueError( 'could not import the ssl module - SSL is not supported on this version of Python' ) if sys.platform == 'cli': # Check that IronPython was launched with -X:Frames and -X:Tracing, since we can't register our trace # func on the thread that calls enable_attach otherwise import clr x_tracing = clr.GetCurrentRuntime().GetLanguageByExtension( 'py').Options.Tracing x_frames = clr.GetCurrentRuntime().GetLanguageByExtension( 'py').Options.Frames if not x_tracing or not x_frames: raise RuntimeError( 'IronPython must be started with -X:Tracing and -X:Frames options to support PTVS remote debugging.' ) global _attach_enabled if _attach_enabled: raise ptvsd.AttachAlreadyEnabledError( 'ptvsd.enable_attach() has already been called in this process.') _attach_enabled = True atexit.register(vspd.detach_process_and_notify_debugger) server = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind(address) server.listen(1) def server_thread_func(): while True: client = None connection = None try: client, addr = server.accept() if certfile: client = ssl.wrap_socket(client, server_side=True, ssl_version=ssl.PROTOCOL_TLSv1, certfile=certfile, keyfile=keyfile) connection = AttachLoop(client, secret, redirect_output, None) connection.send_event( name='legacyRemoteConnected', debuggerName=PTVSDBG, debuggerProtocolVersion=PTVSDBG_VER, ) connection.process_messages() except (socket.error, OSError): pass finally: if connection: connection.close() server_thread = threading.Thread(target=server_thread_func) server_thread.setDaemon(True) server_thread.start() frames = [] f = sys._getframe() while f is not None: frames.append(f) f = f.f_back frames.reverse() cur_thread = vspd.new_thread() for f in frames: cur_thread.push_frame(f) def replace_trace_func(): for f in frames: f.f_trace = cur_thread.trace_func replace_trace_func() sys.settrace(cur_thread.trace_func) vspd.intercept_threads(for_attach=True)
def enable_attach(secret, address=('0.0.0.0', ptvsd.DEFAULT_PORT), certfile=None, keyfile=None, redirect_output=True): if not ssl and (certfile or keyfile): raise ValueError('could not import the ssl module - SSL is not supported on this version of Python') if sys.platform == 'cli': # Check that IronPython was launched with -X:Frames and -X:Tracing, since we can't register our trace # func on the thread that calls enable_attach otherwise import clr x_tracing = clr.GetCurrentRuntime().GetLanguageByExtension('py').Options.Tracing x_frames = clr.GetCurrentRuntime().GetLanguageByExtension('py').Options.Frames if not x_tracing or not x_frames: raise RuntimeError('IronPython must be started with -X:Tracing and -X:Frames options to support PTVS remote debugging.') global _attach_enabled if _attach_enabled: raise ptvsd.AttachAlreadyEnabledError('ptvsd.enable_attach() has already been called in this process.') _attach_enabled = True atexit.register(vspd.detach_process_and_notify_debugger) server = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind(address) server.listen(1) def server_thread_func(): while True: client = None connection = None try: client, addr = server.accept() if certfile: client = ssl.wrap_socket(client, server_side = True, ssl_version = ssl.PROTOCOL_TLSv1, certfile = certfile, keyfile = keyfile) connection = AttachLoop(client, secret, redirect_output, None) connection.send_event( name='legacyRemoteConnected', debuggerName=PTVSDBG, debuggerProtocolVersion=PTVSDBG_VER, ) connection.process_messages() except (socket.error, OSError): pass finally: if connection: connection.close() server_thread = threading.Thread(target = server_thread_func) server_thread.setDaemon(True) server_thread.start() frames = [] f = sys._getframe() while f is not None: frames.append(f) f = f.f_back frames.reverse() cur_thread = vspd.new_thread() for f in frames: cur_thread.push_frame(f) def replace_trace_func(): for f in frames: f.f_trace = cur_thread.trace_func replace_trace_func() sys.settrace(cur_thread.trace_func) vspd.intercept_threads(for_attach = True)