33import re
44import sys
55from _pydev_imps ._pydev_saved_modules import threading
6- from _pydevd_bundle .pydevd_constants import get_global_debugger , IS_WINDOWS , IS_JYTHON , get_current_thread_id
6+ from _pydevd_bundle .pydevd_constants import get_global_debugger , IS_WINDOWS , IS_JYTHON , get_current_thread_id , \
7+ sorted_dict_repr
78from _pydev_bundle import pydev_log
89from contextlib import contextmanager
910from _pydevd_bundle import pydevd_constants
@@ -35,7 +36,7 @@ def _get_apply_arg_patching():
3536 return getattr (_arg_patch , 'apply_arg_patching' , True )
3637
3738
38- def _get_setup_updated_with_protocol (setup ):
39+ def _get_setup_updated_with_protocol_and_ppid (setup , is_exec = False ):
3940 if setup is None :
4041 setup = {}
4142 setup = setup .copy ()
@@ -44,7 +45,11 @@ def _get_setup_updated_with_protocol(setup):
4445 setup .pop (pydevd_constants .ARGUMENT_HTTP_JSON_PROTOCOL , None )
4546 setup .pop (pydevd_constants .ARGUMENT_JSON_PROTOCOL , None )
4647 setup .pop (pydevd_constants .ARGUMENT_QUOTED_LINE_PROTOCOL , None )
47- setup .pop (pydevd_constants .ARGUMENT_HTTP_PROTOCOL , None )
48+
49+ if not is_exec :
50+ # i.e.: The ppid for the subprocess is the current pid.
51+ # If it's an exec, keep it what it was.
52+ setup [pydevd_constants .ARGUMENT_PPID ] = os .getpid ()
4853
4954 protocol = pydevd_constants .get_protocol ()
5055 if protocol == pydevd_constants .HTTP_JSON_PROTOCOL :
@@ -65,18 +70,22 @@ def _get_setup_updated_with_protocol(setup):
6570
6671
6772def _get_python_c_args (host , port , indC , args , setup ):
68- setup = _get_setup_updated_with_protocol (setup )
73+ setup = _get_setup_updated_with_protocol_and_ppid (setup )
74+
75+ # i.e.: We want to make the repr sorted so that it works in tests.
76+ setup_repr = setup if setup is None else (sorted_dict_repr (setup ))
77+
6978 return ("import sys; sys.path.insert(0, r'%s'); import pydevd; pydevd.PydevdCustomization.DEFAULT_PROTOCOL=%r; "
70- "pydevd.settrace(host=%r, port=%s, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=%r, client_access_token=%r); "
71- "from pydevd import SetupHolder; SetupHolder.setup = %s; %s"
79+ "pydevd.settrace(host=%r, port=%s, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=%r, client_access_token=%r, __setup_holder__=%s ); "
80+ "%s"
7281 ) % (
7382 pydev_src_dir ,
7483 pydevd_constants .get_protocol (),
7584 host ,
7685 port ,
7786 setup .get ('access-token' ),
7887 setup .get ('client-access-token' ),
79- setup ,
88+ setup_repr ,
8089 args [indC + 1 ])
8190
8291
@@ -227,7 +236,15 @@ def get_c_option_index(args):
227236 return ind_c
228237
229238
230- def patch_args (args ):
239+ def patch_args (args , is_exec = False ):
240+ '''
241+ :param list args:
242+ Arguments to patch.
243+
244+ :param bool is_exec:
245+ If it's an exec, the current process will be replaced (this means we have
246+ to keep the same ppid).
247+ '''
231248 try :
232249 pydev_log .debug ("Patching args: %s" , args )
233250 args = remove_quotes_from_args (args )
@@ -280,7 +297,9 @@ def patch_args(args):
280297 # ['X:\\pysrc\\pydevd.py', '--multiprocess', '--print-in-debugger-startup',
281298 # '--vm_type', 'python', '--client', '127.0.0.1', '--port', '56352', '--file', 'x:\\snippet1.py']
282299 from _pydevd_bundle .pydevd_command_line_handling import setup_to_argv
283- original = setup_to_argv (_get_setup_updated_with_protocol (SetupHolder .setup )) + ['--file' ]
300+ original = setup_to_argv (
301+ _get_setup_updated_with_protocol_and_ppid (SetupHolder .setup , is_exec = is_exec )
302+ ) + ['--file' ]
284303
285304 module_name = None
286305 m_flag = _get_str_type_compatible (args [i ], '-m' )
@@ -459,7 +478,7 @@ def new_execl(path, *args):
459478 os.execlpe(file, arg0, arg1, ..., env)
460479 """
461480 if _get_apply_arg_patching ():
462- args = patch_args (args )
481+ args = patch_args (args , is_exec = True )
463482 send_process_created_message ()
464483
465484 return getattr (os , original_name )(path , * args )
@@ -475,7 +494,7 @@ def new_execv(path, args):
475494 os.execvp(file, args)
476495 """
477496 if _get_apply_arg_patching ():
478- args = patch_args (args )
497+ args = patch_args (args , is_exec = True )
479498 send_process_created_message ()
480499
481500 return getattr (os , original_name )(path , args )
@@ -491,7 +510,7 @@ def create_execve(original_name):
491510
492511 def new_execve (path , args , env ):
493512 if _get_apply_arg_patching ():
494- args = patch_args (args )
513+ args = patch_args (args , is_exec = True )
495514 send_process_created_message ()
496515
497516 return getattr (os , original_name )(path , args , env )
0 commit comments