-
Notifications
You must be signed in to change notification settings - Fork 14.9k
Fix ExecuteAndWait with empty environment on Windows #158719
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
Conversation
@llvm/pr-subscribers-platform-windows @llvm/pr-subscribers-llvm-support Author: Hiroshi Yamauchi (hjyamauchi) ChangesCreateProcessW requires that the environemnt block to be always double null-terminated even with an empty environemnt. https://learn.microsoft.com/en-us/windows/win32/procthread/environment-variables The attached test fails this way without the fix. C:\Users\hiroshi\upstream\llvm-project\llvm\unittests\Support\ProgramTest.cpp(697): error: Value of: ExecutionFailed Full diff: https://github.com/llvm/llvm-project/pull/158719.diff 2 Files Affected:
diff --git a/llvm/lib/Support/Windows/Program.inc b/llvm/lib/Support/Windows/Program.inc
index 799af5559966c..81385864da85f 100644
--- a/llvm/lib/Support/Windows/Program.inc
+++ b/llvm/lib/Support/Windows/Program.inc
@@ -220,6 +220,10 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
llvm::append_range(EnvBlock, EnvString);
EnvBlock.push_back(0);
}
+ // If an empty environment (*Env is size zero), we need to
+ // terminate with two nulls.
+ if ((*Env).size() == 0)
+ EnvBlock.push_back(0);
EnvBlock.push_back(0);
}
diff --git a/llvm/unittests/Support/ProgramTest.cpp b/llvm/unittests/Support/ProgramTest.cpp
index d30bf458f233c..89ecfd558d2cb 100644
--- a/llvm/unittests/Support/ProgramTest.cpp
+++ b/llvm/unittests/Support/ProgramTest.cpp
@@ -680,4 +680,22 @@ TEST_F(ProgramEnvTest, TestExecuteWithNoStacktraceHandler) {
ASSERT_EQ(0, RetCode);
}
+TEST_F(ProgramEnvTest, TestExecuteEmptyEnvironment) {
+ using namespace llvm::sys;
+
+ std::string Executable =
+ sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
+ StringRef argv[] = {
+ Executable,
+ "--gtest_filter=" // A null invocation to avoid infinite recursion
+ };
+
+ std::string Error;
+ bool ExecutionFailed;
+ int RetCode = ExecuteAndWait(Executable, argv, ArrayRef<StringRef>{}, {}, 0, 0,
+ &Error, &ExecutionFailed);
+ EXPECT_FALSE(ExecutionFailed) << Error;
+ ASSERT_EQ(0, RetCode);
+}
+
} // end anonymous namespace
|
3adfd86
to
e915dad
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
6fb0158
to
98d5e1c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks reasonable to me (but wait a little in case others also want to comment on it)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with a small nit.
llvm/lib/Support/Windows/Program.inc
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Env->size()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also change the comment above to something to this effect: « Empty environments need to be terminated with two nulls. », no need to repeat « *Env is size zero ».
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I missed this comment. I'll follow up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CreateProcessW requires that the environemnt block to be always double null-terminated even with an empty environemnt. https://learn.microsoft.com/en-us/windows/win32/procthread/environment-variables The attached test fails this way without the fix. C:\Users\hiroshi\upstream\llvm-project\llvm\unittests\Support\ProgramTest.cpp(697): error: Value of: ExecutionFailed Actual: true Expected: false Couldn't execute program 'C:\Users\hiroshi\upstream\llvm-project\build\unittests\Support\SupportTests.exe': The parameter is incorrect. (0x57)
98d5e1c
to
9716444
Compare
This testcase fails in my test configurations (e.g. https://github.com/mstorsjo/llvm-mingw/actions/runs/17894399079/job/50879057137). This is because my build environments make binaries that depend on a dynamically linked It would be possible to avoid this issue by copying in This primarily is an issue in mingw build configurations. In theory you could have similar issues in MSVC style environments as well, if linking with What do you think is the best way around this? Just waive this testcase for mingw environments? Or build a separate simple dummy exe as subject for this testcase? I think the former is simpler in practice, and mostly accurate. |
I think so too |
Somehow this managed to cause a regression on Linux! In our LLVM builds we are using libc++ as a standard C++ library. I assume this is still somewhat unusual thing to do, but so far all test cases were passing. Except the one introduced by this commit. It fails as such:
Note that |
…y the lit tests (#538)" It was a horrible solution to the problem introduced by llvm/llvm-project#158719 It caused unexpected issues while testing on RHEL8. This reverts commit 0cc7c83.
…y the lit tests (#538)" It was a horrible solution to the problem introduced by llvm/llvm-project#158719 It caused unexpected issues while testing on RHEL8. This reverts commit 0cc7c83.
Maybe disable the test like #160277? |
Locally, we do this: |
CreateProcessW requires that the environemnt block to be always double null-terminated even with an empty environemnt. https://learn.microsoft.com/en-us/windows/win32/procthread/environment-variables The attached test fails this way without the fix. C:\Users\hiroshi\upstream\llvm-project\llvm\unittests\Support\ProgramTest.cpp(697): error: Value of: ExecutionFailed Actual: true Expected: false Couldn't execute program 'C:\Users\hiroshi\upstream\llvm-project\build\unittests\Support\SupportTests.exe': The parameter is incorrect. (0x57) (Cherry picked from commit 81c55e6)
CreateProcessW requires that the environemnt block to be always double null-terminated even with an empty environemnt.
https://learn.microsoft.com/en-us/windows/win32/procthread/environment-variables
The attached test fails this way without the fix.
C:\Users\hiroshi\upstream\llvm-project\llvm\unittests\Support\ProgramTest.cpp(697): error: Value of: ExecutionFailed
Actual: true
Expected: false
Couldn't execute program 'C:\Users\hiroshi\upstream\llvm-project\build\unittests\Support\SupportTests.exe': The parameter is incorrect. (0x57)