Beispiel #1
0
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 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)
Beispiel #3
0
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)
Beispiel #4
0
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)
Beispiel #5
0
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)
Beispiel #6
0
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)
Beispiel #7
0
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)
Beispiel #9
0
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)
Beispiel #11
0
import add_code_to_python_process
print add_code_to_python_process.run_python_code(
    3736, "print(20)", connect_debugger_tracing=False)
Beispiel #12
0
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)
Beispiel #13
0
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)
Beispiel #14
0
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)
Beispiel #15
0
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)
Beispiel #16
0
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)
Beispiel #17
0
import add_code_to_python_process
print add_code_to_python_process.run_python_code(3736, "print(20)", connect_debugger_tracing=False)
Beispiel #18
0
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")