[testing] Fix signal handling on Windows.

See https://bugs.chromium.org/p/chromium/issues/detail?id=733612#c6
for details.

Also add tests both for windows and non-windows.

Bug: 733612
Change-Id: Id656635a5fc79ea8f805658873599b526e764406
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1796572
Reviewed-by: Dirk Pranke <[email protected]>
Reviewed-by: John Chen <[email protected]>
Commit-Queue: Caleb Rouleau <[email protected]>
Cr-Commit-Position: refs/heads/master@{#695429}
diff --git a/testing/test_env.py b/testing/test_env.py
index 13808a2f..eac46bf 100755
--- a/testing/test_env.py
+++ b/testing/test_env.py
@@ -189,8 +189,8 @@
   assert stdoutfile
   with io.open(stdoutfile, 'wb') as writer, \
       io.open(stdoutfile, 'rb', 1) as reader:
-    process = subprocess.Popen(argv, env=env, cwd=cwd, stdout=writer,
-        stderr=subprocess.STDOUT)
+    process = _popen(argv, env=env, cwd=cwd, stdout=writer,
+                     stderr=subprocess.STDOUT)
     forward_signals([process])
     while process.poll() is None:
       sys.stdout.write(reader.read())
@@ -214,7 +214,7 @@
   """
   if log:
     print('Running %r in %r (env: %r)' % (argv, cwd, env))
-  process = subprocess.Popen(argv, env=env, cwd=cwd, stderr=subprocess.STDOUT)
+  process = _popen(argv, env=env, cwd=cwd, stderr=subprocess.STDOUT)
   forward_signals([process])
   return wait_with_signals(process)
 
@@ -229,7 +229,7 @@
     integer returncode of the subprocess.
   """
   print('Running %r in %r (env: %r)' % (argv, cwd, env))
-  process = subprocess.Popen(
+  process = _popen(
       argv, env=env, cwd=cwd, stderr=file_handle, stdout=file_handle)
   forward_signals([process])
   exit_code = wait_with_signals(process)
@@ -356,9 +356,9 @@
     elif use_symbolization_script:
       # See above comment regarding offline symbolization.
       # Need to pipe to the symbolizer script.
-      p1 = subprocess.Popen(cmd, env=env, stdout=subprocess.PIPE,
-                            stderr=sys.stdout)
-      p2 = subprocess.Popen(
+      p1 = _popen(cmd, env=env, stdout=subprocess.PIPE,
+                  stderr=sys.stdout)
+      p2 = _popen(
           get_sanitizer_symbolize_command(executable_path=cmd[0]),
           env=env, stdin=p1.stdout)
       p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
@@ -375,6 +375,14 @@
     raise
 
 
+def _popen(*args, **kwargs):
+  assert 'creationflags' not in kwargs
+  if sys.platform == 'win32':
+    # Necessary for signal handling. See crbug.com/733612#c6.
+    kwargs['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP
+  return subprocess.Popen(*args, **kwargs)
+
+
 def main():
   return run_executable(sys.argv[1:], os.environ.copy())