Chromium Code Reviews| Index: pylib/gyp/win_tool.py |
| =================================================================== |
| --- pylib/gyp/win_tool.py (revision 1796) |
| +++ pylib/gyp/win_tool.py (working copy) |
| @@ -28,6 +28,76 @@ |
| """This class performs all the Windows tooling steps. The methods can either |
| be executed directly, or dispatched from an argument list.""" |
| + class MsPdbSrvHelper(object): |
| + """This is an helper class to use a unique instance of mspdbsrv.exe for the |
| + linkers linking a .exe target. This helps to reduce the memory pressure one |
|
Sigurður Ásgeirsson
2013/11/25 16:29:57
nit: a->an .exe
Is this factual, though? You also
Sébastien Marchand
2013/11/25 19:24:40
my first goal was to only use the mspdbsrv shardin
|
| + the shared instance of mspdbsrv.exe.""" |
| + |
| + def __init__(self, env, args): |
| + self._is_started = self._MaybeStartMsPdbSrv(env, args) |
|
scottmg
2013/11/23 00:07:26
no _ prefix on member variables
initialize the va
Sébastien Marchand
2013/11/23 04:30:14
Yeah, if I initialize the members here then is_sta
|
| + |
| + def __del__(self): |
|
scottmg
2013/11/23 00:07:26
__del__ isn't good as it's when it happens to get
Sébastien Marchand
2013/11/23 04:30:14
Good to know, thanks. I'll do this.
|
| + if self._is_started: |
| + self._StopMsPdbSrv() |
| + |
| + def _MaybeStartMsPdbSrv(self, env, args): |
| + """Starts an unique instance of mspdbsrv.exe if the given arguments are |
| + those of a linker linking a .exe target.""" |
| + if os.environ.get('GYP_USE_SEPARATE_MSPDBSRV'): |
| + return False |
| + |
| + if len(args) < 1: |
| + raise Exception("Not enough arguments") |
| + |
| + if args[0] != 'link.exe': |
| + return False |
| + |
| + # Checks if this linker produce a PDB for an .exe target. If so use the |
|
Sigurður Ásgeirsson
2013/11/25 16:29:57
nit: produces
Sébastien Marchand
2013/11/26 00:37:56
Done.
|
| + # name of this PDB to generate an endpoint name for mspdbsrv.exe. |
| + endpoint_name = None |
| + for arg in args: |
| + if arg.endswith('exe.pdb'): |
|
Sigurður Ásgeirsson
2013/11/25 16:29:57
interesting, why only .exes? I'd think DLLs are ju
Sigurður Ásgeirsson
2013/11/25 16:29:57
Maybe use a regexp to match the argument and the p
Sébastien Marchand
2013/11/25 19:24:40
For now I'm only doing this for the .exe because I
Sébastien Marchand
2013/11/26 00:37:56
Done.
|
| + endpoint_name = arg[arg.rfind(':') + 1:] + '_mspdbsrv_endpoint' |
|
scottmg
2013/11/23 00:07:26
is the ':' the drive separator? i know i suggested
Sébastien Marchand
2013/11/23 04:30:14
No, it's the beginning of the PDB filename. There'
|
| + break |
| + |
| + if endpoint_name is None: |
| + return False |
| + |
| + # Adds the appropriate environment variable. This will be read by link.exe |
| + # to know which instance of mspdbsrv.exe it should connect to (if it's |
| + # not set then the default endpoint is used). |
|
Sigurður Ásgeirsson
2013/11/25 16:29:57
nit: you might as well go properly unique here and
Sébastien Marchand
2013/11/25 19:24:40
Good point, will do.
|
| + env['_MSPDBSRV_ENDPOINT_'] = endpoint_name |
| + self._env = env |
| + |
| + # Starts the mspdbsrv.exe instance manually. We could specify the endpoint |
| + # in the command line but it's redundant with setting it in the |
| + # environment block. Starting this process manually allows us to wait for |
| + # its completion once the link step is finished. This is required to |
| + # respect the dependencies between the different targets. |
| + mspdbsrv_args = ('mspdbsrv.exe', |
| + '-start', |
| + '-spawn') |
|
scottmg
2013/11/23 00:07:26
when i run "mspdbsrv -start -spawn -endpoint abcd"
Sébastien Marchand
2013/11/23 04:30:14
Yeah it's blocking, but Popen spawn a child proces
|
| + self._mspdbsrv_process = subprocess.Popen(mspdbsrv_args, |
| + shell=True, |
| + env=env, |
| + stdout=subprocess.PIPE, |
| + stderr=subprocess.STDOUT) |
|
scottmg
2013/11/23 00:07:26
i don't think there's any stdout/stderr, but just
Sébastien Marchand
2013/11/23 04:30:14
Good point. Thanks.
|
| + return True |
| + |
| + def _StopMsPdbSrv(self): |
| + """Stop the instance of mspdbsrv.exe that has been started by this |
| + helper.""" |
| + mspdbsrv_stop_args = ('mspdbsrv.exe', |
| + '-stop') |
| + mspdbsrv_stop_process = subprocess.Popen(mspdbsrv_stop_args, |
| + shell=True, |
| + env=self._env, |
| + stdout=subprocess.PIPE, |
| + stderr=subprocess.STDOUT) |
| + _, _ = mspdbsrv_stop_process.communicate() |
|
scottmg
2013/11/23 00:07:26
and these can just be .wait() instead of .communic
Sébastien Marchand
2013/11/23 04:30:14
I'll also use call instead of Popen/communicate fo
|
| + _, _ = self._mspdbsrv_process.communicate() |
| + return |
| + |
| def Dispatch(self, args): |
| """Dispatches a string command to a method.""" |
| if len(args) < 1: |
| @@ -71,6 +141,7 @@ |
| This happens when there are exports from the dll or exe. |
| """ |
| env = self._GetEnv(arch) |
| + mspdbsrv_helper = MsPdbSrvHelper(args, env) |
|
scottmg
2013/11/23 00:07:26
i'm still concerned that there's a race between th
Sébastien Marchand
2013/11/23 04:30:14
I've tried this but it was really crashy, as we're
scottmg
2013/11/23 04:44:12
Hmm, OK. :( See what Siggi thinks, but I'm worried
Sigurður Ásgeirsson
2013/11/25 16:29:57
Well, it's either safe or it isn't. It's safe iff:
Sébastien Marchand
2013/11/25 19:24:40
Ok, so I've used procmon to look at what happen in
|
| popen = subprocess.Popen(args, shell=True, env=env, |
| stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
| out, _ = popen.communicate() |