def main(setup): import add_code_to_python_process show_debug_info_on_target_process = 0 pydevd_dirname = os.path.dirname(os.path.dirname(__file__)) if sys.platform == 'win32': setup['pythonpath'] = pydevd_dirname.replace('\\', '/') setup['pythonpath2'] = os.path.dirname(__file__).replace('\\', '/') python_code = '''import sys; sys.path.append("%(pythonpath)s"); sys.path.append("%(pythonpath2)s"); import attach_script; attach_script.attach(port=%(port)s, host="%(host)s"); '''.replace('\r\n', '').replace('\r', '').replace('\n', '') else: setup['pythonpath'] = pydevd_dirname setup['pythonpath2'] = os.path.dirname(__file__) # We have to pass it a bit differently for gdb python_code = '''import sys; sys.path.append(\\\"%(pythonpath)s\\\"); sys.path.append(\\\"%(pythonpath2)s\\\"); import attach_script; attach_script.attach(port=%(port)s, host=\\\"%(host)s\\\"); '''.replace('\r\n', '').replace('\r', '').replace('\n', '') python_code = python_code % setup add_code_to_python_process.run_python_code( setup['pid'], python_code, connect_debugger_tracing=True, show_debug_info=show_debug_info_on_target_process)
def attach_main(address, pid, *extra, **kwargs): hostname, port_num = address ptvsd_path = os.path.join(ptvsd.__file__, '../..') pydevd_attach_to_process_path = os.path.join( os.path.dirname(pydevd.__file__), 'pydevd_attach_to_process') sys.path.append(pydevd_attach_to_process_path) from add_code_to_python_process import run_python_code # The code must not contain single quotes. Also, it might be running on # a different Python version once it's injected. Encoding string literals # as raw UTF-8 byte values takes care of both. code = ''' ptvsd_path = bytearray({ptvsd_path}).decode("utf-8") hostname = bytearray({hostname}).decode("utf-8") import sys sys.path.insert(0, ptvsd_path) import ptvsd del sys.path[0] from ptvsd._remote import attach attach((hostname, {port_num})) ''' code = code.format( ptvsd_path=repr(list(ptvsd_path.encode('utf-8'))), hostname=repr(list(hostname.encode('utf-8'))), port_num=port_num) run_python_code(pid, code, connect_debugger_tracing=True)
def attach_to_pid(): def quoted_str(s): if s is None: return s assert not isinstance(s, bytes) unescaped = set(chr(ch) for ch in range(32, 127)) - {'"', "'", '\\'} def escape(ch): return ch if ch in unescaped else '\\u%04X' % ord(ch) return 'u"' + ''.join(map(escape, s)) + '"' ptvsd.log.info('Attaching to process with ID {0}', ptvsd.options.target) pid = ptvsd.options.target host = quoted_str(ptvsd.options.host) port = ptvsd.options.port client = ptvsd.options.client log_dir = quoted_str(ptvsd.options.log_dir) ptvsd_path = os.path.abspath(os.path.join(ptvsd.__file__, '../..')) if isinstance(ptvsd_path, bytes): ptvsd_path = ptvsd_path.decode(sys.getfilesystemencoding()) ptvsd_path = quoted_str(ptvsd_path) # pydevd requires injected code to not contain any single quotes. code = ''' import os assert os.getpid() == {pid} import sys sys.path.insert(0, {ptvsd_path}) import ptvsd del sys.path[0] import ptvsd.options ptvsd.options.log_dir = {log_dir} ptvsd.options.client = {client} ptvsd.options.host = {host} ptvsd.options.port = {port} import ptvsd.log ptvsd.log.to_file() ptvsd.log.info("Debugger successfully injected") if ptvsd.options.client: from ptvsd._remote import attach attach(({host}, {port})) else: ptvsd.enable_attach() '''.format(**locals()) ptvsd.log.debug('Injecting debugger into target process: \n"""{0}\n"""'.format(code)) assert "'" not in code, 'Injected code should not contain any single quotes' pydevd_attach_to_process_path = os.path.join( os.path.dirname(pydevd.__file__), 'pydevd_attach_to_process') sys.path.insert(0, pydevd_attach_to_process_path) from add_code_to_python_process import run_python_code run_python_code(pid, code, connect_debugger_tracing=True)
def attach_to_pid(): ptvsd.log.info('Attaching to process with ID {0}', ptvsd.options.target) pid = ptvsd.options.target host = ptvsd.options.host port = ptvsd.options.port client = ptvsd.options.client log_dir = ptvsd.options.log_dir if log_dir is None: log_dir = "" # pydevd requires injected code to not contain any single quotes nor new lines and # double quotes must be escaped properly. pydevd_attach_to_process_path = os.path.join( os.path.dirname(pydevd.__file__), 'pydevd_attach_to_process') sys.path.append(pydevd_attach_to_process_path) import add_code_to_python_process # noqa show_debug_info_on_target_process = 0 # hard-coded (1 to debug) ptvsd_dirname = os.path.dirname(os.path.dirname(__file__)) log_dir = log_dir.replace('\\', '/') setup = { 'host': host, 'port': port, 'client': client, 'log_dir': log_dir, 'pid': pid } if sys.platform == 'win32': setup['pythonpath'] = ptvsd_dirname.replace('\\', '/') python_code = '''import sys; sys.path.append("%(pythonpath)s"); from ptvsd import attach_script_ptvsd_pid; attach_script_ptvsd_pid.attach(port=%(port)s, host="%(host)s", client=%(client)s, log_dir="%(log_dir)s"); '''.replace('\r\n', '').replace('\r', '').replace('\n', '') else: setup['pythonpath'] = ptvsd_dirname # We have to pass it a bit differently for gdb python_code = '''import sys; sys.path.append(\\\"%(pythonpath)s\\\"); from ptvsd import attach_script_ptvsd_pid; attach_script_ptvsd_pid.attach(port=%(port)s, host=\\\"%(host)s\\\", client=%(client)s, log_dir=\\\"%(log_dir)s\\\"); '''.replace('\r\n', '').replace('\r', '').replace('\n', '') python_code = python_code % setup add_code_to_python_process.run_python_code( setup['pid'], python_code, connect_debugger_tracing=True, show_debug_info=show_debug_info_on_target_process)
def attach_to_pid(): def quoted_str(s): assert not isinstance(s, bytes) unescaped = set(chr(ch) for ch in range(32, 127)) - {'"', "'", '\\'} def escape(ch): return ch if ch in unescaped else '\\u%04X' % ord(ch) return 'u"' + ''.join(map(escape, s)) + '"' pid = ptvsd.options.target host = quoted_str(ptvsd.options.host) port = ptvsd.options.port client = ptvsd.options.client ptvsd_path = os.path.abspath(os.path.join(ptvsd.__file__, '../..')) if isinstance(ptvsd_path, bytes): ptvsd_path = ptvsd_path.decode(sys.getfilesystemencoding()) ptvsd_path = quoted_str(ptvsd_path) # pydevd requires injected code to not contain any single quotes. code = ''' import os assert os.getpid() == {pid} import sys sys.path.insert(0, {ptvsd_path}) import ptvsd del sys.path[0] import ptvsd.options ptvsd.options.client = {client} ptvsd.options.host = {host} ptvsd.options.port = {port} if ptvsd.options.client: from ptvsd._remote import attach attach(({host}, {port})) else: ptvsd.enable_attach() '''.format(**locals()) print(code) pydevd_attach_to_process_path = os.path.join( os.path.dirname(pydevd.__file__), 'pydevd_attach_to_process') sys.path.insert(0, pydevd_attach_to_process_path) from add_code_to_python_process import run_python_code run_python_code(pid, code, connect_debugger_tracing=True)
def main(setup): if sys.platform == 'linux': try: output = subprocess.check_output( ['sysctl', 'kernel.yama.ptrace_scope']) if output.decode().strip()[-1] != '0': print( "WARNING: The 'kernel.yama.ptrace_scope' parameter value is not 0, attach to process may not work correctly.\n" " Please run 'sudo sysctl kernel.yama.ptrace_scope=0' to change the value temporary\n" " or add the 'kernel.yama.ptrace_scope = 0' line to /etc/sysctl.d/10-ptrace.conf to set it permanently.", file=sys.stderr) except Exception: traceback.print_exc() import add_code_to_python_process show_debug_info_on_target_process = 0 pydevd_dirname = os.path.dirname(os.path.dirname(__file__)) if sys.platform == 'win32': setup['pythonpath'] = pydevd_dirname.replace('\\', '/') setup['pythonpath2'] = os.path.dirname(__file__).replace('\\', '/') python_code = '''import sys; sys.path.append("%(pythonpath)s"); sys.path.append("%(pythonpath2)s"); import attach_script; attach_script.attach(port=%(port)s, host="%(host)s", protocol="%(protocol)s"); '''.replace('\r\n', '').replace('\r', '').replace('\n', '') else: setup['pythonpath'] = pydevd_dirname setup['pythonpath2'] = os.path.dirname(__file__) # We have to pass it a bit differently for gdb python_code = '''import sys; sys.path.append(\\\"%(pythonpath)s\\\"); sys.path.append(\\\"%(pythonpath2)s\\\"); import attach_script; attach_script.attach(port=%(port)s, host=\\\"%(host)s\\\", protocol=\\\"%(protocol)s\\\"); '''.replace('\r\n', '').replace('\r', '').replace('\n', '') python_code = python_code % setup add_code_to_python_process.run_python_code( setup['pid'], python_code, connect_debugger_tracing=True, show_debug_info=show_debug_info_on_target_process)
def attach_to_pid(): def quoted_str(s): assert not isinstance(s, bytes) unescaped = set(chr(ch) for ch in range(32, 127)) - {'"', "'", '\\'} def escape(ch): return ch if ch in unescaped else '\\u%04X' % ord(ch) return 'u"' + ''.join(map(escape, s)) + '"' pid = ptvsd.options.target host = quoted_str(ptvsd.options.host) port = ptvsd.options.port ptvsd_path = os.path.abspath(os.path.join(ptvsd.__file__, '../..')) if isinstance(ptvsd_path, bytes): ptvsd_path = ptvsd_path.decode(sys.getfilesystemencoding()) ptvsd_path = quoted_str(ptvsd_path) # pydevd requires injected code to not contain any single quotes. code = ''' import os assert os.getpid() == {pid} import sys sys.path.insert(0, {ptvsd_path}) import ptvsd del sys.path[0] import ptvsd.options ptvsd.options.client = True ptvsd.options.host = {host} ptvsd.options.port = {port} ptvsd.enable_attach() '''.format(**locals()) print(code) pydevd_attach_to_process_path = os.path.join( os.path.dirname(pydevd.__file__), 'pydevd_attach_to_process') sys.path.insert(0, pydevd_attach_to_process_path) from add_code_to_python_process import run_python_code run_python_code(pid, code, connect_debugger_tracing=True)
def main(setup): if sys.platform == 'linux': try: output = subprocess.check_output(['sysctl', 'kernel.yama.ptrace_scope']) if output.decode().strip()[-1] != '0': print("WARNING: The 'kernel.yama.ptrace_scope' parameter value is not 0, attach to process may not work correctly.\n" " Please run 'sudo sysctl kernel.yama.ptrace_scope=0' to change the value temporary\n" " or add the 'kernel.yama.ptrace_scope = 0' line to /etc/sysctl.d/10-ptrace.conf to set it permanently.", file=sys.stderr) except Exception: traceback.print_exc() import add_code_to_python_process show_debug_info_on_target_process = 0 pydevd_dirname = os.path.dirname(os.path.dirname(__file__)) if sys.platform == 'win32': setup['pythonpath'] = pydevd_dirname.replace('\\', '/') setup['pythonpath2'] = os.path.dirname(__file__).replace('\\', '/') python_code = '''import sys; sys.path.append("%(pythonpath)s"); sys.path.append("%(pythonpath2)s"); import attach_script; attach_script.attach(port=%(port)s, host="%(host)s"); '''.replace('\r\n', '').replace('\r', '').replace('\n', '') else: setup['pythonpath'] = pydevd_dirname setup['pythonpath2'] = os.path.dirname(__file__) # We have to pass it a bit differently for gdb python_code = '''import sys; sys.path.append(\\\"%(pythonpath)s\\\"); sys.path.append(\\\"%(pythonpath2)s\\\"); import attach_script; attach_script.attach(port=%(port)s, host=\\\"%(host)s\\\"); '''.replace('\r\n', '').replace('\r', '').replace('\n', '') python_code = python_code % setup add_code_to_python_process.run_python_code( setup['pid'], python_code, connect_debugger_tracing=True, show_debug_info=show_debug_info_on_target_process)
import add_code_to_python_process print add_code_to_python_process.run_python_code( 3736, "print(20)", connect_debugger_tracing=False)
def attach_to_pid(): pid = options.target log.info("Attaching to process with PID={0}", pid) encode = lambda s: list(bytearray(s.encode("utf-8")) ) if s is not None else None script_dir = os.path.dirname(debugpy.server.__file__) assert os.path.exists(script_dir) script_dir = encode(script_dir) setup = { "mode": options.mode, "address": options.address, "wait_for_client": options.wait_for_client, "log_to": options.log_to, "adapter_access_token": options.adapter_access_token, } setup = encode(json.dumps(setup)) python_code = """ import codecs; import json; import sys; decode = lambda s: codecs.utf_8_decode(bytearray(s))[0] if s is not None else None; script_dir = decode({script_dir}); setup = json.loads(decode({setup})); sys.path.insert(0, script_dir); import attach_pid_injected; del sys.path[0]; attach_pid_injected.attach(setup); """ python_code = (python_code.replace("\r", "").replace("\n", "").format( script_dir=script_dir, setup=setup)) log.info("Code to be injected: \n{0}", python_code.replace(";", ";\n")) # pydevd restriction on characters in injected code. assert not ( {'"', "'", "\r", "\n"} & set(python_code) ), "Injected code should not contain any single quotes, double quotes, or newlines." pydevd_attach_to_process_path = os.path.join( os.path.dirname(pydevd.__file__), "pydevd_attach_to_process") assert os.path.exists(pydevd_attach_to_process_path) sys.path.append(pydevd_attach_to_process_path) try: import add_code_to_python_process # noqa log.info("Injecting code into process with PID={0} ...", pid) add_code_to_python_process.run_python_code( pid, python_code, connect_debugger_tracing=True, show_debug_info=int( os.getenv("DEBUGPY_ATTACH_BY_PID_DEBUG_INFO", "0")), ) except Exception: log.reraise_exception("Code injection into PID={0} failed:", pid) log.info("Code injection into PID={0} completed.", pid)
def main(setup): import add_code_to_python_process show_debug_info_on_target_process = 0 setup['pydevd_path'] = os.path.dirname( os.path.dirname(inspect.getfile(add_code_to_python_process))) setup['helper_path'] = os.path.dirname( inspect.getfile(add_code_to_python_process)) setup['detach'] = 0 if setup['script'] and setup['debug']: setup['detach'] = 1 if sys.platform == 'win32': python_code = '' if setup['debug']: setup['helper_path'] = setup['helper_path'].replace('\\', '/') setup['pydevd_path'] = setup['pydevd_path'].replace('\\', '/') # Fusion 360 appears to be using a copypasta stdout/stderr redirection based on this stackoverflow answer: # https://stackoverflow.com/a/4307737/531021 # This is problematic because pydev expects there to be a flush method. pydev also adds its own # replacements, which don't have the "value" attribute from the CatchOutErr class that fusion expects. # So we add a noop flush method, and an empty value attribute, and everyone is happy. python_code += ''' import sys sys.path.append("%(helper_path)s") sys.path.append("%(pydevd_path)s") import attach_script sys.stderr.flush = lambda: None sys.stdout.flush = lambda: None attach_script.attach(port=%(port)s, host="%(host)s") sys.stdout.value = "" sys.stderr.value = "" ''' if setup['script']: setup['script'] = setup['script'].replace('\\', '/') python_code += ''' import adsk.core import json import sys helper_running = False try: import fusionIdeaHelperGlobals helper_running = fusionIdeaHelperGlobals.running except: pass if not helper_running: sys.stderr.write("Fusion 360 must be running the helper add-in to facilitate launching scripts.") sys.stderr.write("See https://github.com/JesusFreke/fusionIdea/blob/master/README.md for more information.") else: adsk.core.Application.get().fireCustomEvent( "fusion_idea_run_script", json.dumps({"script": "%(script)s", "detach": %(detach)d})) ''' else: # We have to pass it a bit differently for gdb python_code = '' if setup['debug']: python_code += ''' import sys sys.path.append(\\\"%(helper_path)s\\\") sys.path.append(\\\"%(pydevd_path)s\\\") import attach_script sys.stderr.flush = lambda: None sys.stdout.flush = lambda: None attach_script.attach(port=%(port)s, host=\\\"%(host)s\\\") sys.stdout.value = \\\"\\\" sys.stderr.value = \\\"\\\" ''' if setup['script']: setup['script'] = setup['script'].replace('\\', '/') python_code += ''' import adsk.core import json import sys helper_running = False try: import fusionIdeaHelperGlobals helper_running = fusionIdeaHelperGlobals.running except: pass if not helper_running: sys.stderr.write(\\\"Fusion 360 must be running the helper add-in to facilitate launching scripts.\\\") sys.stderr.write(\\\"See https://github.com/JesusFreke/fusionIdea/blob/master/README.md for more information.\\\") else: adsk.core.Application.get().fireCustomEvent( \\\"fusion_idea_run_script\\\", json.dumps({\\\"script\\\": \\\"%(script)s\\\", \\\"detach\\\": %(detach)d})) ''' python_code = python_code % setup add_code_to_python_process.run_python_code( setup['pid'], python_code, connect_debugger_tracing=setup['debug'], show_debug_info=show_debug_info_on_target_process)
def attach_to_pid(): log.info("Attaching to process with PID={0}", options.target) pid = options.target attach_pid_injected_dirname = os.path.join(os.path.dirname(ptvsd.__file__), "server") assert os.path.exists(attach_pid_injected_dirname) log_dir = (log.log_dir or "").replace("\\", "/") encode = lambda s: list(bytearray(s.encode("utf-8"))) setup = { "script": encode(attach_pid_injected_dirname), "host": encode(options.host), "port": options.port, "client": options.client, "log_dir": encode(log_dir), "client_access_token": encode(options.client_access_token), } python_code = """ import sys; import codecs; decode = lambda s: codecs.utf_8_decode(bytearray(s))[0]; script_path = decode({script}); sys.path.insert(0, script_path); import attach_pid_injected; sys.path.remove(script_path); host = decode({host}); log_dir = decode({log_dir}) or None; client_access_token = decode({client_access_token}) or None; attach_pid_injected.attach( port={port}, host=host, client={client}, log_dir=log_dir, client_access_token=client_access_token, ) """ python_code = python_code.replace("\r", "").replace("\n", "").format(**setup) log.info("Code to be injected: \n{0}", python_code.replace(";", ";\n")) # pydevd restriction on characters in injected code. assert not ( {'"', "'", "\r", "\n"} & set(python_code) ), "Injected code should not contain any single quotes, double quotes, or newlines." pydevd_attach_to_process_path = os.path.join( os.path.dirname(pydevd.__file__), "pydevd_attach_to_process") assert os.path.exists(pydevd_attach_to_process_path) sys.path.append(pydevd_attach_to_process_path) try: import add_code_to_python_process # noqa log.info("Injecting code into process with PID={0} ...", pid) add_code_to_python_process.run_python_code( pid, python_code, connect_debugger_tracing=True, show_debug_info=int( os.getenv("PTVSD_ATTACH_BY_PID_DEBUG_INFO", "0")), ) except Exception: raise log.exception("Code injection into PID={0} failed:", pid) log.info("Code injection into PID={0} completed.", pid)
def main(setup): import add_code_to_python_process show_debug_info_on_target_process = 0 script_path = os.path.abspath(inspect.getfile(inspect.currentframe())) script_name = os.path.splitext(os.path.basename(script_path))[0] script_dir = os.path.dirname(script_path) setup['pydevd_path'] = os.path.dirname( os.path.dirname(inspect.getfile(add_code_to_python_process))) setup['helper_path'] = os.path.dirname( inspect.getfile(add_code_to_python_process)) setup['script_path'] = script_dir setup['detach'] = 0 if setup['script'] and setup['debug']: setup['detach'] = 1 if sys.platform == 'win32': python_code = '' setup['script_path'] = setup['script_path'].replace('\\', '/') if setup['debug']: setup['helper_path'] = setup['helper_path'].replace('\\', '/') setup['pydevd_path'] = setup['pydevd_path'].replace('\\', '/') python_code += ''' import os import sys sys.path.append("%(helper_path)s") sys.path.append("%(pydevd_path)s") os.environ["PYDEVD_USE_FRAME_EVAL"] = "NO" try: import attach_script attach_script.attach(port=%(port)s, host="%(host)s") import _pydevd_bundle.pydevd_comm _pydevd_bundle.pydevd_comm.MAX_IO_MSG_SIZE = 131072 finally: del sys.path[-1] del sys.path[-1] ''' if setup['script']: setup['script'] = setup['script'].replace('\\', '/') python_code += ''' import adsk.core import json import sys sys.path.append("%(script_path)s") try: import fusion_idea_helper finally: del sys.path[-1] adsk.core.Application.get().fireCustomEvent( "fusion_idea_run_script", json.dumps({"script": "%(script)s", "detach": %(detach)d})) ''' else: # We have to pass it a bit differently for gdb python_code = '' if setup['debug']: python_code += ''' import sys sys.path.append(\\\"%(helper_path)s\\\") sys.path.append(\\\"%(pydevd_path)s\\\") try: import attach_script attach_script.attach(port=%(port)s, host=\\\"%(host)s\\\") import _pydevd_bundle.pydevd_comm _pydevd_bundle.pydevd_comm.MAX_IO_MSG_SIZE = 131072 finally del sys.path[-1] del sys.path[-1] ''' if setup['script']: setup['script'] = setup['script'].replace('\\', '/') python_code += ''' import adsk.core import json import sys sys.path.append(\\\"%(script_path)s\\\") try: import fusion_idea_helper finally: del sys.path[-1] adsk.core.Application.get().fireCustomEvent( \\\"fusion_idea_run_script\\\", json.dumps({\\\"script\\\": \\\"%(script)s\\\", \\\"detach\\\": %(detach)d})) ''' python_code = python_code % setup add_code_to_python_process.run_python_code( setup['pid'], python_code, connect_debugger_tracing=setup['debug'], show_debug_info=show_debug_info_on_target_process)
def main(setup): import add_code_to_python_process show_debug_info_on_target_process = 0 script_path = os.path.abspath(inspect.getfile(inspect.currentframe())) script_name = os.path.splitext(os.path.basename(script_path))[0] script_dir = os.path.dirname(script_path) setup['pydevd_path'] = os.path.dirname(os.path.dirname(inspect.getfile(add_code_to_python_process))) setup['helper_path'] = os.path.dirname(inspect.getfile(add_code_to_python_process)) setup['script_path'] = script_dir setup['detach'] = 0 if setup['script'] and setup['debug']: setup['detach'] = 1 if sys.platform == 'darwin': # MacOS python_code = '' if setup['debug']: python_code += ''' import sys sys.path.append("\%(helper_path)s") sys.path.append("%(pydevd_path)s") try: import attach_script sys.stderr.flush = lambda: None sys.stdout.flush = lambda: None attach_script.attach(port=%(port)s, host="%(host)s") sys.stdout.value = "" sys.stderr.value = "" finally del sys.path[-1] del sys.path[-1] ''' if setup['script']: python_code += ''' import adsk.core import json import sys sys.path.append("%(script_path)s") try: import fusion_idea_helper finally: del sys.path[-1] adsk.core.Application.get().fireCustomEvent( "fusion_idea_run_script", json.dumps({"script": "%(script)s", "detach": %(detach)d})) ''' if sys.platform == 'win32': python_code = '' setup['script_path'] = setup['script_path'].replace('\\', '/') if setup['debug']: setup['helper_path'] = setup['helper_path'].replace('\\', '/') setup['pydevd_path'] = setup['pydevd_path'].replace('\\', '/') # Fusion 360 appears to be using a copypasta stdout/stderr redirection based on this stackoverflow answer: # https://stackoverflow.com/a/4307737/531021 # This is problematic because pydev expects there to be a flush method. pydev also adds its own # replacements, which don't have the "dvalue" attribute from the CatchOutErr class that fusion expects. # So we add a noop flush method, and an empty value attribute, and everyone is happy. python_code += ''' import sys sys.path.append("%(helper_path)s") sys.path.append("%(pydevd_path)s") try: import attach_script sys.stderr.flush = lambda: None sys.stdout.flush = lambda: None attach_script.attach(port=%(port)s, host="%(host)s") sys.stdout.value = "" sys.stderr.value = "" finally: del sys.path[-1] del sys.path[-1] ''' if setup['script']: setup['script'] = setup['script'].replace('\\', '/') python_code += ''' import adsk.core import json import sys sys.path.append("%(script_path)s") try: import fusion_idea_helper finally: del sys.path[-1] adsk.core.Application.get().fireCustomEvent( "fusion_idea_run_script", json.dumps({"script": "%(script)s", "detach": %(detach)d})) ''' else: # We have to pass it a bit differently for gdb python_code = '' if setup['debug']: python_code += ''' import sys sys.path.append(\\\"%(helper_path)s\\\") sys.path.append(\\\"%(pydevd_path)s\\\") try: import attach_script sys.stderr.flush = lambda: None sys.stdout.flush = lambda: None attach_script.attach(port=%(port)s, host=\\\"%(host)s\\\") sys.stdout.value = \\\"\\\" sys.stderr.value = \\\"\\\" finally del sys.path[-1] del sys.path[-1] ''' if setup['script']: setup['script'] = setup['script'].replace('\\', '/') python_code += ''' import adsk.core import json import sys sys.path.append(\\\"%(script_path)s\\\") try: import fusion_idea_helper finally: del sys.path[-1] adsk.core.Application.get().fireCustomEvent( \\\"fusion_idea_run_script\\\", json.dumps({\\\"script\\\": \\\"%(script)s\\\", \\\"detach\\\": %(detach)d})) ''' python_code = python_code % setup add_code_to_python_process.run_python_code( setup['pid'], python_code, connect_debugger_tracing=setup['debug'], show_debug_info=show_debug_info_on_target_process)
import add_code_to_python_process print add_code_to_python_process.run_python_code(3736, "print(20)", connect_debugger_tracing=False)
def attach_to_pid(): log.info("Attaching to process with ID {0}", options.target) pid = options.target host = options.host port = options.port client = options.client log_dir = common_opts.log_dir if log_dir is None: log_dir = "" try: attach_pid_injected_dirname = os.path.join( os.path.dirname(ptvsd.__file__), "server") assert os.path.exists(attach_pid_injected_dirname) log_dir = log_dir.replace("\\", "/") encode = lambda s: list(bytearray(s.encode("utf-8"))) setup = { "script": encode(attach_pid_injected_dirname), "host": encode(host), "port": port, "client": client, "log_dir": encode(log_dir), } python_code = """ import sys; import codecs; decode = lambda s: codecs.utf_8_decode(bytearray(s))[0]; script_path = decode({script}); sys.path.insert(0, script_path); import attach_pid_injected; sys.path.remove(script_path); host = decode({host}); log_dir = decode({log_dir}) or None; attach_pid_injected.attach(port={port}, host=host, client={client}, log_dir=log_dir) """ python_code = python_code.replace("\r", "").replace("\n", "").format(**setup) log.info("Code to be injected: \n{0}", python_code.replace(";", ";\n")) # pydevd restriction on characters in injected code. assert not ( {'"', "'", "\r", "\n"} & set(python_code) ), "Injected code should not contain any single quotes, double quots, or newlines." pydevd_attach_to_process_path = os.path.join( os.path.dirname(pydevd.__file__), "pydevd_attach_to_process") assert os.path.exists(pydevd_attach_to_process_path) sys.path.append(pydevd_attach_to_process_path) import add_code_to_python_process # noqa show_debug_info_on_target_process = 0 # hard-coded (1 to debug) log.info("Code injector begin") add_code_to_python_process.run_python_code( pid, python_code, connect_debugger_tracing=True, show_debug_info=show_debug_info_on_target_process, ) except Exception: raise log.exception() log.info("Code injector exiting")