aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/cpp/blaze_util_windows.cc
diff options
context:
space:
mode:
authorGravatar Philipp Wollermann <philwo@google.com>2017-03-15 15:34:11 +0000
committerGravatar Yun Peng <pcloudy@google.com>2017-03-16 08:34:56 +0000
commite4d977ffafa37eefe88b9228ab28b36b0f87d5ee (patch)
tree81c7ab87ff2a261bfc0b24f9dc9eec660da2fac6 /src/main/cpp/blaze_util_windows.cc
parent42ee2a1cb88b695e59ef8c920aa770822633c059 (diff)
windows: Don't try to breakaway from an existing Job in batch mode.
Reasoning: It never worked anyway, because Bazel didn't set the JOB_OBJECT_LIMIT_BREAKAWAY_OK limit on its job. This is why running Bazel in batch mode inside a shell integration test on Windows caused a "CreateProcess() failed: access denied" error. By no longer using CREATE_BREAKAWAY_FROM_JOB, this will instead cause us to use nested jobs, which is exactly the right thing to do: - If our parent dies, we and our children still get reliably killed. - But if *only* we die, then just our children will be reliably killed. If we're on an older Windows that doesn't support nested jobs and are running inside an existing job, we should assume that our parent handles process management - for example like Bazel, which runs all spawned processes in their own job. Also remove the CREATE_NEW_PROCESS_GROUP flag in Bazel's batch mode, because I can't see how this makes sense for a non-daemon process. -- PiperOrigin-RevId: 150194586 MOS_MIGRATED_REVID=150194586
Diffstat (limited to 'src/main/cpp/blaze_util_windows.cc')
-rw-r--r--src/main/cpp/blaze_util_windows.cc49
1 files changed, 26 insertions, 23 deletions
diff --git a/src/main/cpp/blaze_util_windows.cc b/src/main/cpp/blaze_util_windows.cc
index 41a99d00b7..4607491868 100644
--- a/src/main/cpp/blaze_util_windows.cc
+++ b/src/main/cpp/blaze_util_windows.cc
@@ -714,13 +714,16 @@ static bool IsFailureDueToNestedJobsNotSupported(HANDLE process) {
|| version_info.dwMajorVersion == 6 && version_info.dwMinorVersion <= 1;
}
-// Run the given program in the current working directory,
-// using the given argument vector.
+// Run the given program in the current working directory, using the given
+// argument vector, wait for it to finish, then exit ourselves with the exitcode
+// of that program.
void ExecuteProgram(const string& exe, const std::vector<string>& args_vector) {
CmdLine cmdline;
CreateCommandLine(&cmdline, exe, args_vector);
STARTUPINFOA startupInfo = {0};
+ startupInfo.cb = sizeof(STARTUPINFOA);
+
PROCESS_INFORMATION processInfo = {0};
// Propagate BAZEL_SH environment variable to a sub-process.
@@ -730,18 +733,17 @@ void ExecuteProgram(const string& exe, const std::vector<string>& args_vector) {
HANDLE job = CreateJobObject(NULL, NULL);
if (job == NULL) {
- pdie(255, "Error %u while creating job\n", GetLastError());
+ pdie(255, "ExecuteProgram/CreateJobObject: error %u\n", GetLastError());
}
- JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info = { 0 };
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info = {0};
job_info.BasicLimitInformation.LimitFlags =
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
- if (!SetInformationJobObject(
- job,
- JobObjectExtendedLimitInformation,
- &job_info,
- sizeof(job_info))) {
- pdie(255, "Error %u while setting up job\n", GetLastError());
+
+ if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation,
+ &job_info, sizeof(job_info))) {
+ pdie(255, "ExecuteProgram/SetInformationJobObject: error %u\n",
+ GetLastError());
}
BOOL success = CreateProcessA(
@@ -750,10 +752,7 @@ void ExecuteProgram(const string& exe, const std::vector<string>& args_vector) {
/* lpProcessAttributes */ NULL,
/* lpThreadAttributes */ NULL,
/* bInheritHandles */ TRUE,
- /* dwCreationFlags */
- CREATE_NEW_PROCESS_GROUP // So that Ctrl-Break does not affect it
- | CREATE_BREAKAWAY_FROM_JOB // We'll put it in a new job
- | CREATE_SUSPENDED, // So that it doesn't start a new job itself
+ /* dwCreationFlags */ CREATE_SUSPENDED,
/* lpEnvironment */ NULL,
/* lpCurrentDirectory */ NULL,
/* lpStartupInfo */ &startupInfo,
@@ -764,18 +763,22 @@ void ExecuteProgram(const string& exe, const std::vector<string>& args_vector) {
GetLastError(), cmdline.cmdline);
}
- if (!AssignProcessToJobObject(job, processInfo.hProcess)) {
- if (!IsFailureDueToNestedJobsNotSupported(processInfo.hProcess)) {
- pdie(255, "Error %u while assigning process to job\n", GetLastError());
- }
-
- // Otherwise, the OS doesn't support nested jobs so we'll just have to
- // make do without.
+ // We will try to put the launched process into a Job object. This will make
+ // Windows reliably kill all child processes that the process itself may
+ // launch once the process exits. On Windows systems that don't support nested
+ // jobs, this may fail if we are already running inside a job ourselves. In
+ // this case, we'll continue anyway, because we assume that our parent is
+ // handling process management for us.
+ if (!AssignProcessToJobObject(job, processInfo.hProcess) &&
+ !IsFailureDueToNestedJobsNotSupported(processInfo.hProcess)) {
+ pdie(255, "ExecuteProgram/AssignProcessToJobObject: error %u\n",
+ GetLastError());
}
- // Now that we put the process in a new job object, we can start executing it
+ // Now that we potentially put the process into a new job object, we can start
+ // running it.
if (ResumeThread(processInfo.hThread) == -1) {
- pdie(255, "Error %u while starting Java process\n", GetLastError());
+ pdie(255, "ExecuteProgram/ResumeThread: error %u\n", GetLastError());
}
// msys doesn't deliver signals while a Win32 call is pending so we need to