blob: fa8df4cdb3608d10f1dd5281a937e31fb7971453 [file] [log] [blame]
Chris McDonaldc3e0f26b2020-06-04 02:15:141#!/usr/bin/env python
[email protected]0a88a652012-03-09 00:34:452# Copyright (c) 2012 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Sets environment variables needed to run a chromium unit test."""
7
Chris McDonaldc3e0f26b2020-06-04 02:15:148from __future__ import print_function
Trent Aptedb1852432018-01-25 02:15:109import io
[email protected]0a88a652012-03-09 00:34:4510import os
Ben Pastenee5ece812018-06-20 22:39:3411import signal
[email protected]0a88a652012-03-09 00:34:4512import subprocess
13import sys
Trent Aptedb1852432018-01-25 02:15:1014import time
Phillis Tang826c02ff2021-11-17 22:44:2115
Chris McDonaldc3e0f26b2020-06-04 02:15:1416
[email protected]0a88a652012-03-09 00:34:4517# This is hardcoded to be src/ relative to this script.
18ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
19
[email protected]76361be452012-08-30 22:48:1420CHROME_SANDBOX_ENV = 'CHROME_DEVEL_SANDBOX'
21CHROME_SANDBOX_PATH = '/opt/chromium/chrome_sandbox'
22
23
earthdok748e1352015-01-27 23:04:0824def get_sandbox_env(env):
25 """Returns the environment flags needed for the SUID sandbox to work."""
John Abd-El-Malek14ae0542014-10-15 17:52:3126 extra_env = {}
[email protected]76361be452012-08-30 22:48:1427 chrome_sandbox_path = env.get(CHROME_SANDBOX_ENV, CHROME_SANDBOX_PATH)
earthdok748e1352015-01-27 23:04:0828 # The above would silently disable the SUID sandbox if the env value were
29 # an empty string. We don't want to allow that. http://crbug.com/245376
30 # TODO(jln): Remove this check once it's no longer possible to disable the
31 # sandbox that way.
32 if not chrome_sandbox_path:
33 chrome_sandbox_path = CHROME_SANDBOX_PATH
34 extra_env[CHROME_SANDBOX_ENV] = chrome_sandbox_path
John Abd-El-Malek14ae0542014-10-15 17:52:3135
36 return extra_env
37
38
39def trim_cmd(cmd):
40 """Removes internal flags from cmd since they're just used to communicate from
41 the host machine to this script running on the swarm slaves."""
Daniel Cheng232052152022-04-20 00:10:1142 sanitizers = ['asan', 'lsan', 'msan', 'tsan', 'coverage-continuous-mode',
43 'skip-set-lpac-acls']
earthdokeeb065302015-02-04 18:18:0444 internal_flags = frozenset('--%s=%d' % (name, value)
45 for name in sanitizers
46 for value in [0, 1])
John Abd-El-Malek14ae0542014-10-15 17:52:3147 return [i for i in cmd if i not in internal_flags]
[email protected]76361be452012-08-30 22:48:1448
[email protected]0a88a652012-03-09 00:34:4549
[email protected]4bf4d632012-05-31 15:50:3050def fix_python_path(cmd):
51 """Returns the fixed command line to call the right python executable."""
52 out = cmd[:]
53 if out[0] == 'python':
54 out[0] = sys.executable
55 elif out[0].endswith('.py'):
56 out.insert(0, sys.executable)
57 return out
58
59
Nico Weber9417be62021-07-14 23:56:0760def get_sanitizer_env(asan, lsan, msan, tsan, cfi_diag):
61 """Returns the environment flags needed for sanitizer tools."""
John Abd-El-Malek14ae0542014-10-15 17:52:3162
63 extra_env = {}
64
earthdokeeb065302015-02-04 18:18:0465 # Instruct GTK to use malloc while running sanitizer-instrumented tests.
earthdoke6c54a42014-10-16 18:02:3666 extra_env['G_SLICE'] = 'always-malloc'
John Abd-El-Malek14ae0542014-10-15 17:52:3167
68 extra_env['NSS_DISABLE_ARENA_FREE_LIST'] = '1'
69 extra_env['NSS_DISABLE_UNLOAD'] = '1'
70
71 # TODO(glider): remove the symbolizer path once
72 # https://code.google.com/p/address-sanitizer/issues/detail?id=134 is fixed.
Nico Weber19097312016-01-29 18:13:1573 symbolizer_path = os.path.join(ROOT_DIR,
74 'third_party', 'llvm-build', 'Release+Asserts', 'bin', 'llvm-symbolizer')
John Abd-El-Malek14ae0542014-10-15 17:52:3175
earthdokeeb065302015-02-04 18:18:0476 if lsan or tsan:
John Abd-El-Malek14ae0542014-10-15 17:52:3177 # LSan is not sandbox-compatible, so we can use online symbolization. In
78 # fact, it needs symbolization to be able to apply suppressions.
79 symbolization_options = ['symbolize=1',
80 'external_symbolizer_path=%s' % symbolizer_path]
pcc46233c22017-06-20 22:11:4181 elif (asan or msan or cfi_diag) and sys.platform not in ['win32', 'cygwin']:
timurrrr064f9522015-02-12 15:46:3282 # ASan uses a script for offline symbolization, except on Windows.
John Abd-El-Malek14ae0542014-10-15 17:52:3183 # Important note: when running ASan with leak detection enabled, we must use
84 # the LSan symbolization options above.
85 symbolization_options = ['symbolize=0']
vadimsh5cf3c442014-10-20 10:22:3886 # Set the path to llvm-symbolizer to be used by asan_symbolize.py
87 extra_env['LLVM_SYMBOLIZER_PATH'] = symbolizer_path
timurrrr7e67df92015-02-12 21:50:5288 else:
89 symbolization_options = []
John Abd-El-Malek14ae0542014-10-15 17:52:3190
Yves Gerey2e221522019-03-13 08:46:1991 # Leverage sanitizer to print stack trace on abort (e.g. assertion failure).
92 symbolization_options.append('handle_abort=1')
93
earthdokeeb065302015-02-04 18:18:0494 if asan:
95 asan_options = symbolization_options[:]
96 if lsan:
97 asan_options.append('detect_leaks=1')
Ben Pastene536f57c2021-05-17 23:21:5698 # LSan appears to have trouble with later versions of glibc.
99 # See https://github.com/google/sanitizers/issues/1322
100 if 'linux' in sys.platform:
101 asan_options.append('intercept_tls_get_addr=0')
John Abd-El-Malek14ae0542014-10-15 17:52:31102
timurrrr7e67df92015-02-12 21:50:52103 if asan_options:
104 extra_env['ASAN_OPTIONS'] = ' '.join(asan_options)
John Abd-El-Malek14ae0542014-10-15 17:52:31105
earthdokeeb065302015-02-04 18:18:04106 if lsan:
107 if asan or msan:
108 lsan_options = []
109 else:
110 lsan_options = symbolization_options[:]
111 if sys.platform == 'linux2':
112 # Use the debug version of libstdc++ under LSan. If we don't, there will
113 # be a lot of incomplete stack traces in the reports.
114 extra_env['LD_LIBRARY_PATH'] = '/usr/lib/x86_64-linux-gnu/debug:'
115
earthdokeeb065302015-02-04 18:18:04116 extra_env['LSAN_OPTIONS'] = ' '.join(lsan_options)
117
118 if msan:
119 msan_options = symbolization_options[:]
120 if lsan:
121 msan_options.append('detect_leaks=1')
122 extra_env['MSAN_OPTIONS'] = ' '.join(msan_options)
123
124 if tsan:
125 tsan_options = symbolization_options[:]
126 extra_env['TSAN_OPTIONS'] = ' '.join(tsan_options)
John Abd-El-Malek14ae0542014-10-15 17:52:31127
pcc46233c22017-06-20 22:11:41128 # CFI uses the UBSan runtime to provide diagnostics.
129 if cfi_diag:
130 ubsan_options = symbolization_options[:] + ['print_stacktrace=1']
131 extra_env['UBSAN_OPTIONS'] = ' '.join(ubsan_options)
132
John Abd-El-Malek14ae0542014-10-15 17:52:31133 return extra_env
134
Kuan Huang235b0142021-10-19 18:59:28135def get_coverage_continuous_mode_env(env):
136 """Append %c (clang code coverage continuous mode) flag to LLVM_PROFILE_FILE
137 pattern string."""
138 llvm_profile_file = env.get('LLVM_PROFILE_FILE')
139 if not llvm_profile_file:
140 return {}
141
142 dirname, basename = os.path.split(llvm_profile_file)
143 root, ext = os.path.splitext(basename)
144 return {
145 'LLVM_PROFILE_FILE': os.path.join(dirname, root + "%c" + ext)
146 }
John Abd-El-Malek14ae0542014-10-15 17:52:31147
glider9d919342015-02-06 17:42:27148def get_sanitizer_symbolize_command(json_path=None, executable_path=None):
earthdok9bd5d582015-01-29 21:19:36149 """Construct the command to invoke offline symbolization script."""
Nico Weber19097312016-01-29 18:13:15150 script_path = os.path.join(
151 ROOT_DIR, 'tools', 'valgrind', 'asan', 'asan_symbolize.py')
earthdok9bd5d582015-01-29 21:19:36152 cmd = [sys.executable, script_path]
153 if json_path is not None:
154 cmd.append('--test-summary-json-file=%s' % json_path)
glider9d919342015-02-06 17:42:27155 if executable_path is not None:
156 cmd.append('--executable-path=%s' % executable_path)
earthdok9bd5d582015-01-29 21:19:36157 return cmd
158
159
160def get_json_path(cmd):
161 """Extract the JSON test summary path from a command line."""
162 json_path_flag = '--test-launcher-summary-output='
163 for arg in cmd:
164 if arg.startswith(json_path_flag):
165 return arg.split(json_path_flag).pop()
166 return None
167
168
169def symbolize_snippets_in_json(cmd, env):
170 """Symbolize output snippets inside the JSON test summary."""
171 json_path = get_json_path(cmd)
172 if json_path is None:
173 return
174
175 try:
glider9d919342015-02-06 17:42:27176 symbolize_command = get_sanitizer_symbolize_command(
177 json_path=json_path, executable_path=cmd[0])
earthdok9bd5d582015-01-29 21:19:36178 p = subprocess.Popen(symbolize_command, stderr=subprocess.PIPE, env=env)
179 (_, stderr) = p.communicate()
180 except OSError as e:
Chris McDonaldc3e0f26b2020-06-04 02:15:14181 print('Exception while symbolizing snippets: %s' % e, file=sys.stderr)
thakis45643b42016-01-29 21:53:42182 raise
earthdok9bd5d582015-01-29 21:19:36183
184 if p.returncode != 0:
Chris McDonaldc3e0f26b2020-06-04 02:15:14185 print("Error: failed to symbolize snippets in JSON:\n", file=sys.stderr)
186 print(stderr, file=sys.stderr)
thakis45643b42016-01-29 21:53:42187 raise subprocess.CalledProcessError(p.returncode, symbolize_command)
earthdok9bd5d582015-01-29 21:19:36188
189
Trent Aptedb1852432018-01-25 02:15:10190def run_command_with_output(argv, stdoutfile, env=None, cwd=None):
Caleb Rouleaufd511292019-02-22 18:22:00191 """Run command and stream its stdout/stderr to the console & |stdoutfile|.
192
193 Also forward_signals to obey
John Palmera8515fca2021-05-20 03:35:32194 https://chromium.googlesource.com/infra/luci/luci-py/+/main/appengine/swarming/doc/Bot.md#graceful-termination_aka-the-sigterm-and-sigkill-dance
Caleb Rouleaufd511292019-02-22 18:22:00195
196 Returns:
197 integer returncode of the subprocess.
Trent Aptedb1852432018-01-25 02:15:10198 """
Dmitrii Shcherbinineff24402022-04-25 17:41:29199 print('Running %r in %r (env: %r)' % (argv, cwd, env), file=sys.stderr)
Trent Aptedb1852432018-01-25 02:15:10200 assert stdoutfile
Ned Nguyen7f43ff62018-10-04 04:58:46201 with io.open(stdoutfile, 'wb') as writer, \
202 io.open(stdoutfile, 'rb', 1) as reader:
Caleb Rouleau6844df152019-09-11 01:11:59203 process = _popen(argv, env=env, cwd=cwd, stdout=writer,
204 stderr=subprocess.STDOUT)
Ben Pastenee5ece812018-06-20 22:39:34205 forward_signals([process])
Trent Aptedb1852432018-01-25 02:15:10206 while process.poll() is None:
Wenbin Zhange6fafcc2021-11-18 04:25:48207 sys.stdout.write(reader.read().decode('utf-8'))
Caleb Rouleaufd511292019-02-22 18:22:00208 # This sleep is needed for signal propagation. See the
209 # wait_with_signals() docstring.
Trent Aptedb1852432018-01-25 02:15:10210 time.sleep(0.1)
211 # Read the remaining.
Wenbin Zhange6fafcc2021-11-18 04:25:48212 sys.stdout.write(reader.read().decode('utf-8'))
Dmitrii Shcherbinineff24402022-04-25 17:41:29213 print('Command %r returned exit code %d' % (argv, process.returncode),
214 file=sys.stderr)
Trent Aptedb1852432018-01-25 02:15:10215 return process.returncode
216
217
Caleb Rouleaufd511292019-02-22 18:22:00218def run_command(argv, env=None, cwd=None, log=True):
219 """Run command and stream its stdout/stderr both to stdout.
220
221 Also forward_signals to obey
John Palmera8515fca2021-05-20 03:35:32222 https://chromium.googlesource.com/infra/luci/luci-py/+/main/appengine/swarming/doc/Bot.md#graceful-termination_aka-the-sigterm-and-sigkill-dance
Caleb Rouleaufd511292019-02-22 18:22:00223
224 Returns:
225 integer returncode of the subprocess.
226 """
227 if log:
Dmitrii Shcherbinineff24402022-04-25 17:41:29228 print('Running %r in %r (env: %r)' % (argv, cwd, env), file=sys.stderr)
Caleb Rouleau6844df152019-09-11 01:11:59229 process = _popen(argv, env=env, cwd=cwd, stderr=subprocess.STDOUT)
Caleb Rouleaufd511292019-02-22 18:22:00230 forward_signals([process])
Roger Tawabe725ea2021-10-27 12:47:53231 exit_code = wait_with_signals(process)
Weizhong Xiac120b0c2021-11-29 23:12:12232 if log:
Dmitrii Shcherbinineff24402022-04-25 17:41:29233 print('Command returned exit code %d' % exit_code, file=sys.stderr)
Roger Tawabe725ea2021-10-27 12:47:53234 return exit_code
Caleb Rouleaufd511292019-02-22 18:22:00235
236
Caleb Rouleau84e3e812019-05-30 23:34:50237def run_command_output_to_handle(argv, file_handle, env=None, cwd=None):
238 """Run command and stream its stdout/stderr both to |file_handle|.
239
240 Also forward_signals to obey
John Palmera8515fca2021-05-20 03:35:32241 https://chromium.googlesource.com/infra/luci/luci-py/+/main/appengine/swarming/doc/Bot.md#graceful-termination_aka-the-sigterm-and-sigkill-dance
Caleb Rouleau84e3e812019-05-30 23:34:50242
243 Returns:
244 integer returncode of the subprocess.
245 """
Sorin Jianue11c9852019-09-12 20:43:55246 print('Running %r in %r (env: %r)' % (argv, cwd, env))
Caleb Rouleau6844df152019-09-11 01:11:59247 process = _popen(
Caleb Rouleau84e3e812019-05-30 23:34:50248 argv, env=env, cwd=cwd, stderr=file_handle, stdout=file_handle)
249 forward_signals([process])
250 exit_code = wait_with_signals(process)
Sorin Jianue11c9852019-09-12 20:43:55251 print('Command returned exit code %d' % exit_code)
Caleb Rouleau84e3e812019-05-30 23:34:50252 return exit_code
253
254
Caleb Rouleaufd511292019-02-22 18:22:00255def wait_with_signals(process):
256 """A version of process.wait() that works cross-platform.
257
258 This version properly surfaces the SIGBREAK signal.
259
260 From reading the subprocess.py source code, it seems we need to explicitly
261 call time.sleep(). The reason is that subprocess.Popen.wait() on Windows
262 directly calls WaitForSingleObject(), but only time.sleep() properly surface
263 the SIGBREAK signal.
264
265 Refs:
266 https://github.com/python/cpython/blob/v2.7.15/Lib/subprocess.py#L692
267 https://github.com/python/cpython/blob/v2.7.15/Modules/timemodule.c#L1084
268
269 Returns:
270 returncode of the process.
271 """
272 while process.poll() is None:
273 time.sleep(0.1)
274 return process.returncode
275
276
Ben Pastenee5ece812018-06-20 22:39:34277def forward_signals(procs):
278 """Forwards unix's SIGTERM or win's CTRL_BREAK_EVENT to the given processes.
279
280 This plays nicely with swarming's timeout handling. See also
John Palmera8515fca2021-05-20 03:35:32281 https://chromium.googlesource.com/infra/luci/luci-py/+/main/appengine/swarming/doc/Bot.md#graceful-termination_aka-the-sigterm-and-sigkill-dance
Ben Pastenee5ece812018-06-20 22:39:34282
283 Args:
284 procs: A list of subprocess.Popen objects representing child processes.
285 """
286 assert all(isinstance(p, subprocess.Popen) for p in procs)
287 def _sig_handler(sig, _):
288 for p in procs:
Ilia Samsonova00835302019-04-19 17:37:59289 if p.poll() is not None:
290 continue
Andrew Grieve95a2d332018-06-28 02:22:59291 # SIGBREAK is defined only for win32.
292 if sys.platform == 'win32' and sig == signal.SIGBREAK:
Ben Pastenee5ece812018-06-20 22:39:34293 p.send_signal(signal.CTRL_BREAK_EVENT)
294 else:
Weizhong Xiac120b0c2021-11-29 23:12:12295 print("Forwarding signal(%d) to process %d" % (sig, p.pid))
Ben Pastenee5ece812018-06-20 22:39:34296 p.send_signal(sig)
297 if sys.platform == 'win32':
Sebastien Lalancette53ef7d32022-04-26 20:53:45298 signal.signal(signal.SIGBREAK, _sig_handler)
Ben Pastenee5ece812018-06-20 22:39:34299 else:
300 signal.signal(signal.SIGTERM, _sig_handler)
Ilia Samsonova00835302019-04-19 17:37:59301 signal.signal(signal.SIGINT, _sig_handler)
Ben Pastenee5ece812018-06-20 22:39:34302
Haiyang Pan94c26592019-08-13 17:48:11303
Trent Aptedb1852432018-01-25 02:15:10304def run_executable(cmd, env, stdoutfile=None):
[email protected]0a88a652012-03-09 00:34:45305 """Runs an executable with:
Dirk Pranke50e557b2017-12-01 23:48:09306 - CHROME_HEADLESS set to indicate that the test is running on a
307 bot and shouldn't do anything interactive like show modal dialogs.
[email protected]3766ed1c2012-07-26 20:53:56308 - environment variable CR_SOURCE_ROOT set to the root directory.
[email protected]0a88a652012-03-09 00:34:45309 - environment variable LANGUAGE to en_US.UTF-8.
earthdok748e1352015-01-27 23:04:08310 - environment variable CHROME_DEVEL_SANDBOX set
[email protected]0a88a652012-03-09 00:34:45311 - Reuses sys.executable automatically.
312 """
Dirk Pranke50e557b2017-12-01 23:48:09313 extra_env = {
314 # Set to indicate that the executable is running non-interactively on
315 # a bot.
316 'CHROME_HEADLESS': '1',
317
318 # Many tests assume a English interface...
319 'LANG': 'en_US.UTF-8',
320 }
321
[email protected]3766ed1c2012-07-26 20:53:56322 # Used by base/base_paths_linux.cc as an override. Just make sure the default
323 # logic is used.
324 env.pop('CR_SOURCE_ROOT', None)
earthdok748e1352015-01-27 23:04:08325 extra_env.update(get_sandbox_env(env))
John Abd-El-Malek4569c422014-10-09 05:10:53326
327 # Copy logic from tools/build/scripts/slave/runtest.py.
328 asan = '--asan=1' in cmd
329 lsan = '--lsan=1' in cmd
earthdokeeb065302015-02-04 18:18:04330 msan = '--msan=1' in cmd
331 tsan = '--tsan=1' in cmd
pcc46233c22017-06-20 22:11:41332 cfi_diag = '--cfi-diag=1' in cmd
Trent Aptedb1852432018-01-25 02:15:10333 if stdoutfile or sys.platform in ['win32', 'cygwin']:
timurrrr064f9522015-02-12 15:46:32334 # Symbolization works in-process on Windows even when sandboxed.
335 use_symbolization_script = False
336 else:
Ilia Samsonov4ea016762019-12-02 22:11:13337 # If any sanitizer is enabled, we print unsymbolized stack trace
338 # that is required to run through symbolization script.
339 use_symbolization_script = (asan or msan or cfi_diag or lsan or tsan)
John Abd-El-Malek4569c422014-10-09 05:10:53340
pcc46233c22017-06-20 22:11:41341 if asan or lsan or msan or tsan or cfi_diag:
Nico Weber9417be62021-07-14 23:56:07342 extra_env.update(get_sanitizer_env(asan, lsan, msan, tsan, cfi_diag))
earthdokeeb065302015-02-04 18:18:04343
Timur Iskhodzhanovfdbfd4e12015-02-05 13:50:23344 if lsan or tsan:
345 # LSan and TSan are not sandbox-friendly.
346 cmd.append('--no-sandbox')
John Abd-El-Malek14ae0542014-10-15 17:52:31347
Kuan Huang235b0142021-10-19 18:59:28348 # Enable clang code coverage continuous mode.
349 if '--coverage-continuous-mode=1' in cmd:
350 extra_env.update(get_coverage_continuous_mode_env(env))
351
Daniel Cheng232052152022-04-20 00:10:11352 if '--skip-set-lpac-acls=1' not in cmd and sys.platform == 'win32':
353 sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
354 'scripts'))
Sebastien Lalancette53ef7d32022-04-26 20:53:45355 import common
Daniel Cheng232052152022-04-20 00:10:11356 common.set_lpac_acls(ROOT_DIR, is_test_script=True)
357
John Abd-El-Malek14ae0542014-10-15 17:52:31358 cmd = trim_cmd(cmd)
John Abd-El-Malek4569c422014-10-09 05:10:53359
[email protected]8ba98352012-05-23 20:43:59360 # Ensure paths are correctly separated on windows.
361 cmd[0] = cmd[0].replace('/', os.path.sep)
[email protected]4bf4d632012-05-31 15:50:30362 cmd = fix_python_path(cmd)
John Abd-El-Malek14ae0542014-10-15 17:52:31363
Dirk Pranke2cf1a152019-04-03 01:34:38364 # We also want to print the GTEST env vars that were set by the caller,
365 # because you need them to reproduce the task properly.
366 env_to_print = extra_env.copy()
367 for env_var_name in ('GTEST_SHARD_INDEX', 'GTEST_TOTAL_SHARDS'):
Chris McDonaldc3e0f26b2020-06-04 02:15:14368 if env_var_name in env:
369 env_to_print[env_var_name] = env[env_var_name]
Dirk Pranke2cf1a152019-04-03 01:34:38370
Sorin Jianue11c9852019-09-12 20:43:55371 print('Additional test environment:\n%s\n'
John Abd-El-Malek14ae0542014-10-15 17:52:31372 'Command: %s\n' % (
Dirk Pranke2b9bec72020-11-18 04:33:38373 '\n'.join(' %s=%s' % (k, v)
374 for k, v in sorted(env_to_print.items())),
Sorin Jianue11c9852019-09-12 20:43:55375 ' '.join(cmd)))
maruelf00125f82016-11-19 00:01:14376 sys.stdout.flush()
John Abd-El-Malek14ae0542014-10-15 17:52:31377 env.update(extra_env or {})
[email protected]50ec9f232012-03-16 04:18:23378 try:
Trent Aptedb1852432018-01-25 02:15:10379 if stdoutfile:
380 # Write to stdoutfile and poll to produce terminal output.
381 return run_command_with_output(cmd, env=env, stdoutfile=stdoutfile)
Sebastien Lalancette53ef7d32022-04-26 20:53:45382 elif use_symbolization_script:
Trent Aptedb1852432018-01-25 02:15:10383 # See above comment regarding offline symbolization.
John Abd-El-Malek4569c422014-10-09 05:10:53384 # Need to pipe to the symbolizer script.
Caleb Rouleau6844df152019-09-11 01:11:59385 p1 = _popen(cmd, env=env, stdout=subprocess.PIPE,
386 stderr=sys.stdout)
387 p2 = _popen(
glider9d919342015-02-06 17:42:27388 get_sanitizer_symbolize_command(executable_path=cmd[0]),
389 env=env, stdin=p1.stdout)
John Abd-El-Malek4569c422014-10-09 05:10:53390 p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
Ben Pastenee5ece812018-06-20 22:39:34391 forward_signals([p1, p2])
Caleb Rouleaufd511292019-02-22 18:22:00392 wait_with_signals(p1)
393 wait_with_signals(p2)
earthdok9bd5d582015-01-29 21:19:36394 # Also feed the out-of-band JSON output to the symbolizer script.
395 symbolize_snippets_in_json(cmd, env)
vadimsh1eaeb2982014-10-20 12:28:45396 return p1.returncode
Sebastien Lalancette53ef7d32022-04-26 20:53:45397 else:
398 return run_command(cmd, env=env, log=False)
[email protected]50ec9f232012-03-16 04:18:23399 except OSError:
Chris McDonaldc3e0f26b2020-06-04 02:15:14400 print('Failed to start %s' % cmd, file=sys.stderr)
[email protected]50ec9f232012-03-16 04:18:23401 raise
[email protected]0a88a652012-03-09 00:34:45402
403
Caleb Rouleau6844df152019-09-11 01:11:59404def _popen(*args, **kwargs):
405 assert 'creationflags' not in kwargs
406 if sys.platform == 'win32':
407 # Necessary for signal handling. See crbug.com/733612#c6.
408 kwargs['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP
409 return subprocess.Popen(*args, **kwargs)
410
411
[email protected]0a88a652012-03-09 00:34:45412def main():
gliderb73f1872014-10-09 16:24:56413 return run_executable(sys.argv[1:], os.environ.copy())
[email protected]0a88a652012-03-09 00:34:45414
415
[email protected]ed763a72012-08-29 03:51:22416if __name__ == '__main__':
[email protected]0a88a652012-03-09 00:34:45417 sys.exit(main())