diff options
| author | Brad King <brad.king@kitware.com> | 2024-01-22 19:55:47 (GMT) |
|---|---|---|
| committer | Brad King <brad.king@kitware.com> | 2024-01-24 22:10:00 (GMT) |
| commit | bcbb212df704d36736731aa567b291fd97401804 (patch) | |
| tree | 6fef8b57dd7aa10c9f15447b18dc74951de68dad /Source/cmcmd.cxx | |
| parent | adb3e13d323aeb19c3824112cfa712cc122db3b4 (diff) | |
| download | CMake-bcbb212df704d36736731aa567b291fd97401804.zip CMake-bcbb212df704d36736731aa567b291fd97401804.tar.gz CMake-bcbb212df704d36736731aa567b291fd97401804.tar.bz2 | |
Revert use of libuv for process execution for 3.28
Wide use of CMake 3.28.{1,0[-rcN]} has uncovered some hangs and crashes
in libuv SIGCHLD handling on some platforms, particularly in virtualization
environments on macOS hosts. Although the bug does not seem to be in CMake,
we can restore stability in the CMake 3.28 release series for users of such
platforms by reverting our new uses of libuv for process execution.
Revert implementation changes merged by commit 4771544386 (Merge topic
'replace-cmsysprocess-with-cmuvprocesschain', 2023-09-06, v3.28.0-rc1~138),
but keep test suite updates.
Issue: #25414, #25500, #25562, #25589
Diffstat (limited to 'Source/cmcmd.cxx')
| -rw-r--r-- | Source/cmcmd.cxx | 97 |
1 files changed, 58 insertions, 39 deletions
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 5bf8edc..9d7bf50 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -72,6 +72,7 @@ #include "cmsys/Directory.hxx" #include "cmsys/FStream.hxx" +#include "cmsys/Process.h" #include "cmsys/RegularExpression.hxx" #include "cmsys/Terminal.h" @@ -294,8 +295,14 @@ int CLCompileAndDependencies(const std::vector<std::string>& args) } } - cmUVProcessChainBuilder builder; - builder.AddCommand(command).SetWorkingDirectory(currentBinaryDir); + std::unique_ptr<cmsysProcess, void (*)(cmsysProcess*)> cp( + cmsysProcess_New(), cmsysProcess_Delete); + std::vector<const char*> argv(command.size() + 1); + std::transform(command.begin(), command.end(), argv.begin(), + [](std::string const& s) { return s.c_str(); }); + argv.back() = nullptr; + cmsysProcess_SetCommand(cp.get(), argv.data()); + cmsysProcess_SetWorkingDirectory(cp.get(), currentBinaryDir.c_str()); cmsys::ofstream fout(depFile.c_str()); if (!fout) { @@ -306,18 +313,22 @@ int CLCompileAndDependencies(const std::vector<std::string>& args) CLOutputLogger errLogger(std::cerr); // Start the process. - auto result = - cmProcessTools::RunProcess(builder, &includeParser, &errLogger); - auto const& subStatus = result.front(); + cmProcessTools::RunProcess(cp.get(), &includeParser, &errLogger); int status = 0; // handle status of process - if (subStatus.SpawnResult != 0) { - status = 2; - } else if (subStatus.TermSignal != 0) { - status = 1; - } else { - status = static_cast<int>(subStatus.ExitStatus); + switch (cmsysProcess_GetState(cp.get())) { + case cmsysProcess_State_Exited: + status = cmsysProcess_GetExitValue(cp.get()); + break; + case cmsysProcess_State_Exception: + status = 1; + break; + case cmsysProcess_State_Error: + status = 2; + break; + default: + break; } if (status != 0) { @@ -1105,8 +1116,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args, int ret = 0; auto time_start = std::chrono::steady_clock::now(); - cmSystemTools::RunSingleCommand(command, nullptr, nullptr, &ret, nullptr, - cmSystemTools::OUTPUT_PASSTHROUGH); + cmSystemTools::RunSingleCommand(command, nullptr, nullptr, &ret); auto time_finish = std::chrono::steady_clock::now(); std::chrono::duration<double> time_elapsed = time_finish - time_start; @@ -1880,6 +1890,21 @@ int cmcmd::ExecuteLinkScript(std::vector<std::string> const& args) } } + // Allocate a process instance. + cmsysProcess* cp = cmsysProcess_New(); + if (!cp) { + std::cerr << "Error allocating process instance in link script." + << std::endl; + return 1; + } + + // Children should share stdout and stderr with this process. + cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDOUT, 1); + cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1); + + // Run the command lines verbatim. + cmsysProcess_SetOption(cp, cmsysProcess_Option_Verbatim, 1); + // Read command lines from the script. cmsys::ifstream fin(args[2].c_str()); if (!fin) { @@ -1897,21 +1922,9 @@ int cmcmd::ExecuteLinkScript(std::vector<std::string> const& args) continue; } - // Allocate a process instance. - cmUVProcessChainBuilder builder; - - // Children should share stdout and stderr with this process. - builder.SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT, stdout) - .SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR, stderr); - // Setup this command line. - std::vector<std::string> args2; -#ifdef _WIN32 - cmSystemTools::ParseWindowsCommandLine(command.c_str(), args2); -#else - cmSystemTools::ParseUnixCommandLine(command.c_str(), args2); -#endif - builder.AddCommand(args2); + const char* cmd[2] = { command.c_str(), nullptr }; + cmsysProcess_SetCommand(cp, cmd); // Report the command if verbose output is enabled. if (verbose) { @@ -1919,29 +1932,35 @@ int cmcmd::ExecuteLinkScript(std::vector<std::string> const& args) } // Run the command and wait for it to exit. - auto chain = builder.Start(); - chain.Wait(); + cmsysProcess_Execute(cp); + cmsysProcess_WaitForExit(cp, nullptr); // Report failure if any. - auto const& status = chain.GetStatus(0); - auto exception = status.GetException(); - switch (exception.first) { - case cmUVProcessChain::ExceptionCode::None: - if (status.ExitStatus != 0) { - result = static_cast<int>(status.ExitStatus); + switch (cmsysProcess_GetState(cp)) { + case cmsysProcess_State_Exited: { + int value = cmsysProcess_GetExitValue(cp); + if (value != 0) { + result = value; } + } break; + case cmsysProcess_State_Exception: + std::cerr << "Error running link command: " + << cmsysProcess_GetExceptionString(cp) << std::endl; + result = 1; break; - case cmUVProcessChain::ExceptionCode::Spawn: - std::cerr << "Error running link command: " << exception.second; + case cmsysProcess_State_Error: + std::cerr << "Error running link command: " + << cmsysProcess_GetErrorString(cp) << std::endl; result = 2; break; default: - std::cerr << "Error running link command: " << exception.second; - result = 1; break; } } + // Free the process instance. + cmsysProcess_Delete(cp); + // Return the final resulting return value. return result; } |
