Commit 922ad5c6 authored by Brad King's avatar Brad King Committed by Kitware Robot
Browse files

Merge topic 'execute_process-command-error'

e5a4ffaa

 execute_process: Improve COMMAND_ERROR_IS_FATAL error capture scenarios
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Merge-request: !5588
parents 0a6c7cdd e5a4ffaa
......@@ -6,8 +6,10 @@
#include <cctype> /* isspace */
#include <cstdio>
#include <iostream>
#include <map>
#include <memory>
#include <sstream>
#include <utility>
#include <vector>
#include <cm/string_view>
......@@ -375,47 +377,101 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
}
}
if (arguments.CommandErrorIsFatal == "ANY"_s) {
if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exited) {
std::vector<int> failedIndexes;
for (int i = 0; i < static_cast<int>(arguments.Commands.size()); ++i) {
if (cmsysProcess_GetStateByIndex(cp, i) ==
kwsysProcess_StateByIndex_Exited) {
int exitCode = cmsysProcess_GetExitValueByIndex(cp, i);
if (exitCode) {
failedIndexes.push_back(i);
}
auto queryProcessStatusByIndex = [&cp](int index) -> std::string {
std::string processStatus;
switch (cmsysProcess_GetStateByIndex(cp, static_cast<int>(index))) {
case kwsysProcess_StateByIndex_Exited: {
int exitCode = cmsysProcess_GetExitValueByIndex(cp, index);
if (exitCode) {
processStatus = "Child return code: " + std::to_string(exitCode);
}
} break;
case kwsysProcess_StateByIndex_Exception: {
processStatus = cmStrCat(
"Abnormal exit with child return code: ",
cmsysProcess_GetExceptionStringByIndex(cp, static_cast<int>(index)));
break;
}
if (!failedIndexes.empty()) {
std::ostringstream oss;
oss << "failed command indexes: ";
for (auto i = 0u; i < failedIndexes.size(); i++) {
if (i == failedIndexes.size() - 1) {
oss << failedIndexes[i] + 1;
} else {
oss << failedIndexes[i] + 1 << ", ";
case kwsysProcess_StateByIndex_Error:
default:
processStatus = "Error getting the child return code";
break;
}
return processStatus;
};
if (arguments.CommandErrorIsFatal == "ANY"_s) {
bool ret = true;
switch (cmsysProcess_GetState(cp)) {
case cmsysProcess_State_Exited: {
std::map<int, std::string> failureIndices;
for (int i = 0; i < static_cast<int>(arguments.Commands.size()); ++i) {
std::string processStatus = queryProcessStatusByIndex(i);
if (!processStatus.empty()) {
failureIndices[i] = processStatus;
}
if (!failureIndices.empty()) {
std::ostringstream oss;
oss << "failed command indexes:\n";
for (auto const& e : failureIndices) {
oss << " " << e.first + 1 << ": \"" << e.second << "\"\n";
}
status.SetError(oss.str());
ret = false;
}
}
status.SetError(oss.str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
} break;
case cmsysProcess_State_Exception:
status.SetError(
cmStrCat("abnormal exit: ", cmsysProcess_GetExceptionString(cp)));
ret = false;
break;
case cmsysProcess_State_Error:
status.SetError(cmStrCat("error getting child return code: ",
cmsysProcess_GetErrorString(cp)));
ret = false;
break;
case cmsysProcess_State_Expired:
status.SetError("Process terminated due to timeout");
ret = false;
break;
}
if (!ret) {
cmSystemTools::SetFatalErrorOccured();
return false;
}
}
if (arguments.CommandErrorIsFatal == "LAST"_s) {
if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exited) {
int lastIndex = static_cast<int>(arguments.Commands.size() - 1);
if (cmsysProcess_GetStateByIndex(cp, lastIndex) ==
kwsysProcess_StateByIndex_Exited) {
int exitCode = cmsysProcess_GetExitValueByIndex(cp, lastIndex);
if (exitCode) {
bool ret = true;
switch (cmsysProcess_GetState(cp)) {
case cmsysProcess_State_Exited: {
int lastIndex = static_cast<int>(arguments.Commands.size() - 1);
const std::string processStatus = queryProcessStatusByIndex(lastIndex);
if (!processStatus.empty()) {
status.SetError("last command failed");
cmSystemTools::SetFatalErrorOccured();
return false;
ret = false;
}
}
} break;
case cmsysProcess_State_Exception:
status.SetError(
cmStrCat("Abnormal exit: ", cmsysProcess_GetExceptionString(cp)));
ret = false;
break;
case cmsysProcess_State_Error:
status.SetError(cmStrCat("Error getting child return code: ",
cmsysProcess_GetErrorString(cp)));
ret = false;
break;
case cmsysProcess_State_Expired:
status.SetError("Process terminated due to timeout");
ret = false;
break;
}
if (!ret) {
cmSystemTools::SetFatalErrorOccured();
return false;
}
}
......
......@@ -316,7 +316,10 @@ add_RunCMake_test(add_subdirectory)
add_RunCMake_test(add_test)
add_RunCMake_test(build_command)
add_executable(exit_code exit_code.c)
set(execute_process_ARGS -DEXIT_CODE_EXE=$<TARGET_FILE:exit_code>)
set(execute_process_ARGS
-DEXIT_CODE_EXE=$<TARGET_FILE:exit_code>
-DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}
)
if(NOT CMake_TEST_EXTERNAL_CMAKE)
list(APPEND execute_process_ARGS -DTEST_ENCODING_EXE=$<TARGET_FILE:testEncoding>)
endif()
......
CMake Error at .*AnyCommandAbnormalExit.cmake:[0-9]+ \(execute_process\):
execute_process failed command indexes:
1: "Abnormal exit with child return code: Segmentation fault
execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c
"import os; os.kill(os.getpid(),11)"
COMMAND ${CMAKE_COMMAND} -E true
COMMAND_ERROR_IS_FATAL ANY
)
CMake Error at .*AnyCommandError.cmake:1 \(execute_process\):
execute_process failed command indexes: 2, 3, 4
execute_process failed command indexes:
2: "Child return code: 1"
3: "Child return code: 1"
execute_process(COMMAND ${CMAKE_COMMAND} -E true
COMMAND ${CMAKE_COMMAND} -E false
COMMAND ${CMAKE_COMMAND} -E false
COMMAND ${CMAKE_COMMAND} -E false
COMMAND ${CMAKE_COMMAND} -E true
COMMAND ${CMAKE_COMMAND} -E true
COMMAND_ERROR_IS_FATAL ANY
COMMAND ${CMAKE_COMMAND} -E false
COMMAND ${CMAKE_COMMAND} -E false
COMMAND ${CMAKE_COMMAND} -E true
COMMAND_ERROR_IS_FATAL ANY
)
execute_process(COMMAND ${CMAKE_COMMAND} -E true
COMMAND ${CMAKE_COMMAND} -E true
COMMAND_ERROR_IS_FATAL ANY
)
CMake Error at .*AnyCommandTimeout.cmake:9 \(execute_process\):
execute_process Process terminated due to timeout
execute_process(COMMAND ${CMAKE_COMMAND} -E true
COMMAND ${CMAKE_COMMAND} -E sleep 10
COMMAND ${CMAKE_COMMAND} -E true
TIMEOUT 1
RESULT_VARIABLE result
)
if(NOT result EQUAL "0")
execute_process(COMMAND ${CMAKE_COMMAND} -E true
COMMAND ${CMAKE_COMMAND} -E sleep 10
COMMAND ${CMAKE_COMMAND} -E true
TIMEOUT 1
COMMAND_ERROR_IS_FATAL ANY
)
endif()
execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c
"import os; os.kill(os.getpid(),11)"
COMMAND ${CMAKE_COMMAND} -E true
RESULT_VARIABLE result
)
if(result EQUAL "0")
execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c
"import os; os.kill(os.getpid(),11)"
COMMAND ${CMAKE_COMMAND} -E true
COMMAND_ERROR_IS_FATAL LAST
)
endif()
CMake Error at .*LastCommandAbnormalExit-2.cmake:[0-9]+ \(execute_process\):
execute_process Abnormal exit: Segmentation fault
execute_process(COMMAND ${CMAKE_COMMAND} -E true
COMMAND "${PYTHON_EXECUTABLE}" -c
"import os; os.kill(os.getpid(),11)"
RESULT_VARIABLE result
)
if(NOT result EQUAL "0")
execute_process(COMMAND ${CMAKE_COMMAND} -E true
COMMAND "${PYTHON_EXECUTABLE}" -c
"import os; os.kill(os.getpid(),11)"
COMMAND_ERROR_IS_FATAL LAST
)
endif()
CMake Error at .*LastCommandError.cmake:1 \(execute_process\):
CMake Error at .*LastCommandError.cmake:11 \(execute_process\):
execute_process last command failed
execute_process(COMMAND ${CMAKE_COMMAND} -E true
COMMAND ${CMAKE_COMMAND} -E false
COMMAND ${CMAKE_COMMAND} -E false
COMMAND ${CMAKE_COMMAND} -E false
COMMAND ${CMAKE_COMMAND} -E true
COMMAND ${CMAKE_COMMAND} -E false
RESULT_VARIABLE result
)
if(NOT result EQUAL "0")
execute_process(COMMAND ${CMAKE_COMMAND} -E true
COMMAND ${CMAKE_COMMAND} -E false
COMMAND ${CMAKE_COMMAND} -E false
COMMAND ${CMAKE_COMMAND} -E false
COMMAND ${CMAKE_COMMAND} -E true
COMMAND ${CMAKE_COMMAND} -E false
COMMAND_ERROR_IS_FATAL LAST
)
)
endif()
execute_process(COMMAND ${CMAKE_COMMAND} -E true
COMMAND ${CMAKE_COMMAND} -E false
COMMAND ${CMAKE_COMMAND} -E false
COMMAND ${CMAKE_COMMAND} -E true
RESULT_VARIABLE result
)
if(result EQUAL "0")
execute_process(COMMAND ${CMAKE_COMMAND} -E true
COMMAND ${CMAKE_COMMAND} -E false
COMMAND ${CMAKE_COMMAND} -E false
COMMAND ${CMAKE_COMMAND} -E true
COMMAND_ERROR_IS_FATAL LAST
)
endif()
CMake Error at .*LastCommandTimeout.cmake:9 \(execute_process\):
execute_process Process terminated due to timeout
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment