public override bool TryResumeProcess() => false; // Currently, only SandboxedProcess is supported. /// <inheritdoc /> public override async Task <SandboxedProcessResult> GetResultAsync() { Contract.Requires(m_processExecutor != null); // See the remarks of this class that BuildXL wants to execute a process P with SandboxedProcessInfo I // in the VM. // (1) Wait for VmCommandProxy to exit. await m_processExecutor.WaitForExitAsync(); await m_processExecutor.WaitForStdOutAndStdErrAsync(); // (2) Validate result of VmCommandProxy. if (m_processExecutor.TimedOut || m_processExecutor.Killed) { // If timed out/killed, then sandboxed process result may have not been deserialized yet. return(CreateResultForVmCommandProxyFailure()); } // Process.ExitCode is the exit code of VmCommandProxy, and not the exit code of SandboxedProcessExecutor // nor the exit code of the process P. if (Process.ExitCode != 0) { return(CreateResultForVmCommandProxyFailure()); } if (!FileUtilities.FileExistsNoFollow(RunOutputPath)) { m_error.AppendLine($"Could not find VM output file '{RunOutputPath}"); return(CreateResultForVmCommandProxyFailure()); } try { // (3) Validate the result of SandboxedProcessExecutor(P, I) that VmCommandProxy instructs the VM to execute. RunResult runVmResult = ExceptionUtilities.HandleRecoverableIOException( () => VmSerializer.DeserializeFromFile <RunResult>(RunOutputPath), e => m_error.AppendLine(e.Message)); if (runVmResult == null) { return(CreateResultForVmCommandProxyFailure()); } // runVmResult.ProcessStateInfo.ExitCode is the exit code of SandboxedProcessExecutor, and not // the exit code of the process P that SandboxedProcessExecutor executes. if (runVmResult.ProcessStateInfo.ExitCode != 0) { return(CreateResultForSandboxExecutorFailure(runVmResult)); } } catch (Exception e) { m_error.AppendLine(e.ToString()); return(CreateResultForVmCommandProxyFailure()); } return(DeserializeSandboxedProcessResultFromFile()); }
public override async Task <SandboxedProcessResult> GetResultAsync() { Contract.Requires(m_processExecutor != null); // (1) Wait for VmCommandProxy. await m_processExecutor.WaitForExitAsync(); await m_processExecutor.WaitForStdOutAndStdErrAsync(); // (2) Validate result of VmCommandProxy. if (m_processExecutor.TimedOut || m_processExecutor.Killed) { // If timed out/killed, then sandboxed process result may have not been deserialized yet. return(CreateResultForVmCommandProxyFailure()); } if (Process.ExitCode != 0) { return(CreateResultForVmCommandProxyFailure()); } if (!FileUtilities.FileExistsNoFollow(RunOutputPath)) { m_error.AppendLine($"Could not find VM output file '{RunOutputPath}"); return(CreateResultForVmCommandProxyFailure()); } try { // (3) Validate the result of sandboxed process executor run by VmCommandProxy. RunResult runVmResult = ExceptionUtilities.HandleRecoverableIOException( () => VmSerializer.DeserializeFromFile <RunResult>(RunOutputPath), e => m_error.AppendLine(e.Message)); if (runVmResult == null) { return(CreateResultForVmCommandProxyFailure()); } if (runVmResult.ProcessStateInfo.ExitCode != 0) { return(CreateResultForSandboxExecutorFailure(runVmResult)); } } catch (Exception e) { m_error.AppendLine(e.ToString()); return(CreateResultForVmCommandProxyFailure()); } return(DeserializeSandboxedProcessResultFromFile()); }
/// <inheritdoc /> public async Task <SandboxedProcessResult> GetResultAsync() { Contract.Requires(Started); SandboxedProcessReports reports = null; await m_processExecutor.WaitForExitAsync(); if (m_processExecutor.Killed) { // call here this.KillAsync() because a subclass may override it // to do some extra processing when a process is killed await KillAsync(); } LogProcessState("Waiting for reports to be received"); reports = await GetReportsAsync(); m_reportsReceivedTime = DateTime.UtcNow; reports?.Freeze(); await m_processExecutor.WaitForStdOutAndStdErrAsync(); var reportFileAccesses = ProcessInfo.FileAccessManifest?.ReportFileAccesses == true; var fileAccesses = reportFileAccesses ? (reports?.FileAccesses ?? s_emptyFileAccessesSet) : null; return(new SandboxedProcessResult { ExitCode = m_processExecutor.TimedOut ? ExitCodes.Timeout : Process.ExitCode, Killed = Killed, TimedOut = m_processExecutor.TimedOut, HasDetoursInjectionFailures = HasSandboxFailures, JobAccountingInformation = GetJobAccountingInfo(), StandardOutput = m_output.Freeze(), StandardError = m_error.Freeze(), HasReadWriteToReadFileAccessRequest = reports?.HasReadWriteToReadFileAccessRequest ?? false, AllUnexpectedFileAccesses = reports?.FileUnexpectedAccesses ?? s_emptyFileAccessesSet, FileAccesses = fileAccesses, DetouringStatuses = reports?.ProcessDetoursStatuses, ExplicitlyReportedFileAccesses = reports?.ExplicitlyReportedFileAccesses, Processes = CoalesceProcesses(reports?.Processes), MessageProcessingFailure = reports?.MessageProcessingFailure, DumpCreationException = m_dumpCreationException, DumpFileDirectory = ProcessInfo.TimeoutDumpDirectory, PrimaryProcessTimes = GetProcessTimes(), SurvivingChildProcesses = CoalesceProcesses(GetSurvivingChildProcesses()) }); }
/// <inheritdoc /> public override async Task <SandboxedProcessResult> GetResultAsync() { Contract.Requires(m_processExecutor != null); await m_processExecutor.WaitForExitAsync(); await m_processExecutor.WaitForStdOutAndStdErrAsync(); if (m_processExecutor.TimedOut || m_processExecutor.Killed) { // If timed out/killed, then sandboxed process result may have not been deserialized yet. return(CreateResultForFailure()); } if (Process.ExitCode != 0) { return(CreateResultForFailure()); } return(DeserializeSandboxedProcessResultFromFile()); }