-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Revert "[flang] Fix execute_command_line cmdstat is not set when error occurs" #96365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…r occurs…" This reverts commit 4232dd5.
@llvm/pr-subscribers-flang-runtime Author: Kiran Chandramohan (kiranchandramohan) ChangesReverts llvm/llvm-project#93023 Reverting due to buildbot failure. Full diff: https://github.com/llvm/llvm-project/pull/96365.diff 3 Files Affected:
diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md
index d1f7cd8372e24..8853d4d9e1c79 100644
--- a/flang/docs/Intrinsics.md
+++ b/flang/docs/Intrinsics.md
@@ -893,17 +893,16 @@ used in constant expressions have currently no folding support at all.
##### `CMDSTAT`:
- Synchronous execution:
- - -2: `ASYNC_NO_SUPPORT_ERR` - No error condition occurs, but `WAIT` is present with the value `false`, and the processor does not support asynchronous execution.
- - -1: `NO_SUPPORT_ERR` - The processor does not support command line execution. (system returns -1 with errno `ENOENT`)
- - 0: `CMD_EXECUTED` - Command executed with no error.
+ - -2: No error condition occurs, but `WAIT` is present with the value `false`, and the processor does not support asynchronous execution.
+ - -1: The processor does not support command line execution.
- \+ (positive value): An error condition occurs.
- - 1: `FORK_ERR` - Fork Error (occurs only on POSIX-compatible systems).
- - 2: `EXECL_ERR` - Execution Error (system returns -1 with other errno).
- - 3: `COMMAND_EXECUTION_ERR` - Invalid Command Error (exit code 1).
- - 4: `COMMAND_CANNOT_EXECUTE_ERR` - Command Cannot Execute Error (Linux exit code 126).
- - 5: `COMMAND_NOT_FOUND_ERR` - Command Not Found Error (Linux exit code 127).
- - 6: `INVALID_CL_ERR` - Invalid Command Line Error (covers all other non-zero exit codes).
- - 7: `SIGNAL_ERR` - Signal error (either stopped or killed by signal, occurs only on POSIX-compatible systems).
+ - 1: Fork Error (occurs only on POSIX-compatible systems).
+ - 2: Execution Error (command exits with status -1).
+ - 3: Invalid Command Error (determined by the exit code depending on the system).
+ - On Windows: exit code is 1.
+ - On POSIX-compatible systems: exit code is 127 or 126.
+ - 4: Signal error (either stopped or killed by signal, occurs only on POSIX-compatible systems).
+ - 0: Otherwise.
- Asynchronous execution:
- 0 will always be assigned.
diff --git a/flang/runtime/execute.cpp b/flang/runtime/execute.cpp
index c7f8f386d81f4..0f5bc5059e21d 100644
--- a/flang/runtime/execute.cpp
+++ b/flang/runtime/execute.cpp
@@ -13,10 +13,8 @@
#include "tools.h"
#include "flang/Runtime/descriptor.h"
#include <cstdlib>
-#include <errno.h>
#include <future>
#include <limits>
-
#ifdef _WIN32
#include "flang/Common/windows-include.h"
#else
@@ -34,16 +32,13 @@ namespace Fortran::runtime {
// and the processor does not support asynchronous execution. Otherwise it is
// assigned the value 0
enum CMD_STAT {
- ASYNC_NO_SUPPORT_ERR = -2, // system returns -1 with ENOENT
- NO_SUPPORT_ERR = -1, // Linux setsid() returns -1
- CMD_EXECUTED = 0, // command executed with no error
- FORK_ERR = 1, // Linux fork() returns < 0
- EXECL_ERR = 2, // system returns -1 with other errno
- COMMAND_EXECUTION_ERR = 3, // exit code 1
- COMMAND_CANNOT_EXECUTE_ERR = 4, // Linux exit code 126
- COMMAND_NOT_FOUND_ERR = 5, // Linux exit code 127
- INVALID_CL_ERR = 6, // cover all other non-zero exit code
- SIGNAL_ERR = 7
+ ASYNC_NO_SUPPORT_ERR = -2,
+ NO_SUPPORT_ERR = -1,
+ CMD_EXECUTED = 0,
+ FORK_ERR = 1,
+ EXECL_ERR = 2,
+ INVALID_CL_ERR = 3,
+ SIGNAL_ERR = 4
};
// Override CopyCharsToDescriptor in tools.h, pass string directly
@@ -67,86 +62,24 @@ void CheckAndStoreIntToDescriptor(
// If a condition occurs that would assign a nonzero value to CMDSTAT but
// the CMDSTAT variable is not present, error termination is initiated.
-std::int64_t TerminationCheck(std::int64_t status, const Descriptor *cmdstat,
+int TerminationCheck(int status, const Descriptor *cmdstat,
const Descriptor *cmdmsg, Terminator &terminator) {
- // On both Windows and Linux, errno is set when system returns -1.
if (status == -1) {
- // On Windows, ENOENT means the command interpreter can't be found.
- // On Linux, system calls execl with filepath "/bin/sh", ENOENT means the
- // file pathname does not exist.
- if (errno == ENOENT) {
- if (!cmdstat) {
- terminator.Crash("Command line execution is not supported, system "
- "returns -1 with errno ENOENT.");
- } else {
- StoreIntToDescriptor(cmdstat, NO_SUPPORT_ERR, terminator);
- CheckAndCopyCharsToDescriptor(cmdmsg,
- "Command line execution is not supported, system returns -1 with "
- "errno ENOENT.");
- }
+ if (!cmdstat) {
+ terminator.Crash("Execution error with system status code: %d", status);
} else {
- char err_buffer[30];
- char msg[]{"Execution error with system status code: -1, errno: "};
-#ifdef _WIN32
- if (strerror_s(err_buffer, sizeof(err_buffer), errno) != 0)
-#else
- if (strerror_r(errno, err_buffer, sizeof(err_buffer)) != 0)
-#endif
- terminator.Crash("errno to char msg failed.");
- char *newMsg{static_cast<char *>(AllocateMemoryOrCrash(
- terminator, std::strlen(msg) + std::strlen(err_buffer) + 1))};
- std::strcat(newMsg, err_buffer);
-
- if (!cmdstat) {
- terminator.Crash(newMsg);
- } else {
- StoreIntToDescriptor(cmdstat, EXECL_ERR, terminator);
- CheckAndCopyCharsToDescriptor(cmdmsg, newMsg);
- }
- FreeMemory(newMsg);
+ StoreIntToDescriptor(cmdstat, EXECL_ERR, terminator);
+ CheckAndCopyCharsToDescriptor(cmdmsg, "Execution error");
}
}
-
#ifdef _WIN32
// On WIN32 API std::system returns exit status directly
- std::int64_t exitStatusVal{status};
- if (exitStatusVal != 0) {
- if (!cmdstat) {
- terminator.Crash(
- "Invalid command quit with exit status code: %d", exitStatusVal);
- } else {
- StoreIntToDescriptor(cmdstat, INVALID_CL_ERR, terminator);
- CheckAndCopyCharsToDescriptor(cmdmsg, "Invalid command line");
- }
- }
-#else
- std::int64_t exitStatusVal{WEXITSTATUS(status)};
+ int exitStatusVal{status};
if (exitStatusVal == 1) {
- if (!cmdstat) {
- terminator.Crash("Command line execution failed with exit code: 1.");
- } else {
- StoreIntToDescriptor(cmdstat, COMMAND_EXECUTION_ERR, terminator);
- CheckAndCopyCharsToDescriptor(
- cmdmsg, "Command line execution failed with exit code: 1.");
- }
- } else if (exitStatusVal == 126) {
- if (!cmdstat) {
- terminator.Crash("Command cannot be executed with exit code: 126.");
- } else {
- StoreIntToDescriptor(cmdstat, COMMAND_CANNOT_EXECUTE_ERR, terminator);
- CheckAndCopyCharsToDescriptor(
- cmdmsg, "Command cannot be executed with exit code: 126.");
- }
- } else if (exitStatusVal == 127) {
- if (!cmdstat) {
- terminator.Crash("Command not found with exit code: 127.");
- } else {
- StoreIntToDescriptor(cmdstat, COMMAND_NOT_FOUND_ERR, terminator);
- CheckAndCopyCharsToDescriptor(
- cmdmsg, "Command not found with exit code: 127.");
- }
- // capture all other nonzero exit code
- } else if (exitStatusVal != 0) {
+#else
+ int exitStatusVal{WEXITSTATUS(status)};
+ if (exitStatusVal == 127 || exitStatusVal == 126) {
+#endif
if (!cmdstat) {
terminator.Crash(
"Invalid command quit with exit status code: %d", exitStatusVal);
@@ -155,26 +88,23 @@ std::int64_t TerminationCheck(std::int64_t status, const Descriptor *cmdstat,
CheckAndCopyCharsToDescriptor(cmdmsg, "Invalid command line");
}
}
-#endif
-
#if defined(WIFSIGNALED) && defined(WTERMSIG)
if (WIFSIGNALED(status)) {
if (!cmdstat) {
- terminator.Crash("Killed by signal: %d", WTERMSIG(status));
+ terminator.Crash("killed by signal: %d", WTERMSIG(status));
} else {
StoreIntToDescriptor(cmdstat, SIGNAL_ERR, terminator);
- CheckAndCopyCharsToDescriptor(cmdmsg, "Killed by signal");
+ CheckAndCopyCharsToDescriptor(cmdmsg, "killed by signal");
}
}
#endif
-
#if defined(WIFSTOPPED) && defined(WSTOPSIG)
if (WIFSTOPPED(status)) {
if (!cmdstat) {
- terminator.Crash("Stopped by signal: %d", WSTOPSIG(status));
+ terminator.Crash("stopped by signal: %d", WSTOPSIG(status));
} else {
StoreIntToDescriptor(cmdstat, SIGNAL_ERR, terminator);
- CheckAndCopyCharsToDescriptor(cmdmsg, "Stopped by signal");
+ CheckAndCopyCharsToDescriptor(cmdmsg, "stopped by signal");
}
}
#endif
@@ -204,9 +134,8 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
if (wait) {
// either wait is not specified or wait is true: synchronous mode
- std::int64_t status{std::system(newCmd)};
- std::int64_t exitStatusVal{
- TerminationCheck(status, cmdstat, cmdmsg, terminator)};
+ int status{std::system(newCmd)};
+ int exitStatusVal{TerminationCheck(status, cmdstat, cmdmsg, terminator)};
// If sync, assigned processor-dependent exit status. Otherwise unchanged
CheckAndStoreIntToDescriptor(exitstat, exitStatusVal, terminator);
} else {
@@ -244,7 +173,7 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
terminator.Crash(
"CreateProcess failed with error code: %lu.", GetLastError());
} else {
- StoreIntToDescriptor(cmdstat, ASYNC_NO_SUPPORT_ERR, terminator);
+ StoreIntToDescriptor(cmdstat, (uint32_t)GetLastError(), terminator);
CheckAndCopyCharsToDescriptor(cmdmsg, "CreateProcess failed.");
}
}
@@ -272,7 +201,7 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
}
exit(EXIT_FAILURE);
}
- std::int64_t status{std::system(newCmd)};
+ int status{std::system(newCmd)};
TerminationCheck(status, cmdstat, cmdmsg, terminator);
exit(status);
}
diff --git a/flang/unittests/Runtime/CommandTest.cpp b/flang/unittests/Runtime/CommandTest.cpp
index 20bd7a5b5ff35..08daa4ba37f26 100644
--- a/flang/unittests/Runtime/CommandTest.cpp
+++ b/flang/unittests/Runtime/CommandTest.cpp
@@ -311,8 +311,8 @@ TEST_F(ZeroArguments, GetCommand) { CheckCommandValue(commandOnlyArgv, 1); }
TEST_F(ZeroArguments, ECLValidCommandAndPadSync) {
OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
bool wait{true};
- OwningPtr<Descriptor> exitStat{IntDescriptor(404)};
- OwningPtr<Descriptor> cmdStat{IntDescriptor(202)};
+ OwningPtr<Descriptor> exitStat{EmptyIntDescriptor()};
+ OwningPtr<Descriptor> cmdStat{EmptyIntDescriptor()};
OwningPtr<Descriptor> cmdMsg{CharDescriptor("No change")};
RTNAME(ExecuteCommandLine)
@@ -339,91 +339,40 @@ TEST_F(ZeroArguments, ECLValidCommandStatusSetSync) {
CheckDescriptorEqStr(cmdMsg.get(), "No change");
}
-TEST_F(ZeroArguments, ECLGeneralErrorCommandErrorSync) {
- OwningPtr<Descriptor> command{CharDescriptor("cat GeneralErrorCommand")};
- bool wait{true};
- OwningPtr<Descriptor> exitStat{IntDescriptor(404)};
- OwningPtr<Descriptor> cmdStat{IntDescriptor(202)};
- OwningPtr<Descriptor> cmdMsg{CharDescriptor("cmd msg buffer XXXXXXXXXXXXXX")};
-
- RTNAME(ExecuteCommandLine)
- (*command.get(), wait, exitStat.get(), cmdStat.get(), cmdMsg.get());
-#ifdef _WIN32
- CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 1);
- CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 6);
- CheckDescriptorEqStr(cmdMsg.get(), "Invalid command lineXXXXXXXXX");
-#else
- CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 1);
- CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 3);
- CheckDescriptorEqStr(cmdMsg.get(), "Command line execution failed");
-#endif
-}
-
-TEST_F(ZeroArguments, ECLNotExecutedCommandErrorSync) {
- OwningPtr<Descriptor> command{CharDescriptor(
- "touch NotExecutedCommandFile && chmod -x NotExecutedCommandFile && "
- "./NotExecutedCommandFile")};
- bool wait{true};
- OwningPtr<Descriptor> exitStat{IntDescriptor(404)};
- OwningPtr<Descriptor> cmdStat{IntDescriptor(202)};
- OwningPtr<Descriptor> cmdMsg{CharDescriptor("cmd msg buffer XXXXXXXX")};
-
- RTNAME(ExecuteCommandLine)
- (*command.get(), wait, exitStat.get(), cmdStat.get(), cmdMsg.get());
-#ifdef _WIN32
- CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 1);
- CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 6);
- CheckDescriptorEqStr(cmdMsg.get(), "Invalid command lineXXX");
-#else
- CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 126);
- CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 4);
- CheckDescriptorEqStr(cmdMsg.get(), "Command cannot be execu");
- // removing the file only on Linux (file is not created on Win)
- OwningPtr<Descriptor> commandClean{
- CharDescriptor("rm -f NotExecutedCommandFile")};
- OwningPtr<Descriptor> cmdMsgNoErr{CharDescriptor("No Error")};
- RTNAME(ExecuteCommandLine)
- (*commandClean.get(), wait, exitStat.get(), cmdStat.get(), cmdMsgNoErr.get());
- CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 0);
- CheckDescriptorEqStr(cmdMsgNoErr.get(), "No Error");
- CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 0);
-#endif
-}
-
-TEST_F(ZeroArguments, ECLNotFoundCommandErrorSync) {
- OwningPtr<Descriptor> command{CharDescriptor("NotFoundCommand")};
+TEST_F(ZeroArguments, ECLInvalidCommandErrorSync) {
+ OwningPtr<Descriptor> command{CharDescriptor("InvalidCommand")};
bool wait{true};
OwningPtr<Descriptor> exitStat{IntDescriptor(404)};
OwningPtr<Descriptor> cmdStat{IntDescriptor(202)};
- OwningPtr<Descriptor> cmdMsg{CharDescriptor("unmodified buffer XXXXXXXXX")};
+ OwningPtr<Descriptor> cmdMsg{CharDescriptor("Message ChangedXXXXXXXXX")};
RTNAME(ExecuteCommandLine)
(*command.get(), wait, exitStat.get(), cmdStat.get(), cmdMsg.get());
#ifdef _WIN32
- CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 1);
- CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 6);
- CheckDescriptorEqStr(cmdMsg.get(), "Invalid command lineXXXXXXX");
+ CheckDescriptorEqInt(exitStat.get(), 1);
#else
CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 127);
- CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 5);
- CheckDescriptorEqStr(cmdMsg.get(), "Command not found with exit");
#endif
+ CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 3);
+ CheckDescriptorEqStr(cmdMsg.get(), "Invalid command lineXXXX");
}
TEST_F(ZeroArguments, ECLInvalidCommandTerminatedSync) {
OwningPtr<Descriptor> command{CharDescriptor("InvalidCommand")};
bool wait{true};
+ OwningPtr<Descriptor> exitStat{IntDescriptor(404)};
OwningPtr<Descriptor> cmdMsg{CharDescriptor("No Change")};
#ifdef _WIN32
EXPECT_DEATH(RTNAME(ExecuteCommandLine)(
- *command.get(), wait, nullptr, nullptr, cmdMsg.get()),
+ *command.get(), wait, exitStat.get(), nullptr, cmdMsg.get()),
"Invalid command quit with exit status code: 1");
#else
EXPECT_DEATH(RTNAME(ExecuteCommandLine)(
- *command.get(), wait, nullptr, nullptr, cmdMsg.get()),
- "Command not found with exit code: 127.");
+ *command.get(), wait, exitStat.get(), nullptr, cmdMsg.get()),
+ "Invalid command quit with exit status code: 127");
#endif
+ CheckDescriptorEqInt(exitStat.get(), 404);
CheckDescriptorEqStr(cmdMsg.get(), "No Change");
}
@@ -445,10 +394,13 @@ TEST_F(ZeroArguments, ECLValidCommandAndExitStatNoChangeAndCMDStatusSetAsync) {
TEST_F(ZeroArguments, ECLInvalidCommandParentNotTerminatedAsync) {
OwningPtr<Descriptor> command{CharDescriptor("InvalidCommand")};
bool wait{false};
+ OwningPtr<Descriptor> exitStat{IntDescriptor(404)};
OwningPtr<Descriptor> cmdMsg{CharDescriptor("No change")};
EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
- *command.get(), wait, nullptr, nullptr, cmdMsg.get()));
+ *command.get(), wait, exitStat.get(), nullptr, cmdMsg.get()));
+
+ CheckDescriptorEqInt(exitStat.get(), 404);
CheckDescriptorEqStr(cmdMsg.get(), "No change");
}
|
yiwu0b11
added a commit
to yiwu0b11/llvm-project
that referenced
this pull request
Jun 26, 2024
…hen error occurs" (llvm#96365)" The fix broke llvm-test-suite, so it was reverted previousely. With test fixes added in llvm/llvm-test-suite#137, it should now pass the tests This reverts commit 4356356.
yiwu0b11
added a commit
that referenced
this pull request
Jun 27, 2024
…hen error occurs" (#96365)" (#96774) The fix broke llvm-test-suite, so it was reverted previously. With test fixes added in llvm/llvm-test-suite#137, it should now pass the tests This reverts commit 4356356.
lravenclaw
pushed a commit
to lravenclaw/llvm-project
that referenced
this pull request
Jul 3, 2024
…hen error occurs" (llvm#96365)" (llvm#96774) The fix broke llvm-test-suite, so it was reverted previously. With test fixes added in llvm/llvm-test-suite#137, it should now pass the tests This reverts commit 4356356.
AlexisPerry
pushed a commit
to llvm-project-tlp/llvm-project
that referenced
this pull request
Jul 9, 2024
…r occurs" (llvm#96365) Reverts llvm#93023 Reverting due to buildbot failure. https://lab.llvm.org/buildbot/#/builders/41/builds/227 test-suite :: Fortran/gfortran/regression/gfortran-regression-execute-regression__execute_command_line_3_f90
AlexisPerry
pushed a commit
to llvm-project-tlp/llvm-project
that referenced
this pull request
Jul 9, 2024
…hen error occurs" (llvm#96365)" (llvm#96774) The fix broke llvm-test-suite, so it was reverted previously. With test fixes added in llvm/llvm-test-suite#137, it should now pass the tests This reverts commit 4356356.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Reverts #93023
Reverting due to buildbot failure.
https://lab.llvm.org/buildbot/#/builders/41/builds/227
test-suite :: Fortran/gfortran/regression/gfortran-regression-execute-regression__execute_command_line_3_f90