[llvm] [CAS] Close the stderr temp file of the out-of-process validator (PR #226844)
Vladimir Shiryaev via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 27 15:14:27 PDT 2026
https://github.com/tagolog created https://github.com/llvm/llvm-project/pull/226844
`validateOutOfProcess` creates a temporary file via `createTemporaryFile` overload that returns a descriptor. The descriptor is never used and never closed, so it leaks on every platform.
On Windows the leak also breaks validation. `ExecuteAndWait` reopens the path in `RedirectIO` (llvm/lib/Support/Windows/Program.inc) with `CreateFileW(..., GENERIC_WRITE, FILE_SHARE_READ, ...)`. The code tries to open the file with FILE_SHARE_READ while it is still open for write because of the descriptor that is still not closed. The call fails with the error message:
```
can't redirect stderr: The process cannot access the file because it
is being used by another process. (0x20)
```
Thus, execution never reaches the external validator. When recovery is allowed, `validateIfNeeded` treats this failure as a CAS corruption.
The fix is to use the path-only `createTemporaryFile` overload, which closes the file right after creating it.
>From e64e2f55e8985bdbcc95a7dc2ca2a0e8d0e62468 Mon Sep 17 00:00:00 2001
From: Vladimir Shiryaev <w at tagolog.com>
Date: Sun, 27 Sep 2026 14:05:38 -0700
Subject: [PATCH] [CAS] Close the stderr temp file of the out-of-process
validator
`validateOutOfProcess` creates a temporary file via `createTemporaryFile`
overload that returns a descriptor. The descriptor is never used
and never closed, so it leaks on every platform.
On Windows the leak also breaks validation. `ExecuteAndWait` reopens the
path in `RedirectIO` (llvm/lib/Support/Windows/Program.inc) with
`CreateFileW(..., GENERIC_WRITE, FILE_SHARE_READ, ...)`.
The code tries to open the file with FILE_SHARE_READ while it is still
open for write because of the descriptor that is still not closed.
The call fails with the error message:
can't redirect stderr: The process cannot access the file because it
is being used by another process. (0x20)
Thus, execution never reaches the external validator.
When recovery is allowed, `validateIfNeeded` treats this failure as a
CAS corruption.
The fix is to use the path-only `createTemporaryFile` overload,
which closes the file right after creating it.
---
llvm/lib/CAS/UnifiedOnDiskCache.cpp | 3 +--
llvm/test/tools/llvm-cas/validate-if-needed.test | 7 +++++++
2 files changed, 8 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/tools/llvm-cas/validate-if-needed.test
diff --git a/llvm/lib/CAS/UnifiedOnDiskCache.cpp b/llvm/lib/CAS/UnifiedOnDiskCache.cpp
index 3d0a8b3eba135..ea8cbe8ca292b 100644
--- a/llvm/lib/CAS/UnifiedOnDiskCache.cpp
+++ b/llvm/lib/CAS/UnifiedOnDiskCache.cpp
@@ -214,9 +214,8 @@ static Error validateOutOfProcess(StringRef LLVMCasBinary, StringRef RootPath,
Args.push_back("-check-hash");
llvm::SmallString<128> StdErrPath;
- int StdErrFD = -1;
if (std::error_code EC = sys::fs::createTemporaryFile(
- "llvm-cas-validate-stderr", "txt", StdErrFD, StdErrPath,
+ "llvm-cas-validate-stderr", "txt", StdErrPath,
llvm::sys::fs::OF_Text))
return createStringError(EC, "failed to create temporary file");
FileRemover OutputRemover(StdErrPath.c_str());
diff --git a/llvm/test/tools/llvm-cas/validate-if-needed.test b/llvm/test/tools/llvm-cas/validate-if-needed.test
new file mode 100644
index 0000000000000..2412cf15bfcc2
--- /dev/null
+++ b/llvm/test/tools/llvm-cas/validate-if-needed.test
@@ -0,0 +1,7 @@
+RUN: rm -rf %t
+RUN: mkdir %t
+
+RUN: llvm-cas --cas %t/cas --make-blob --data %S/Inputs/oneline
+
+RUN: llvm-cas --cas %t/cas --validate-if-needed --force | FileCheck %s
+CHECK: validated successfully
More information about the llvm-commits
mailing list