From 9c4591d7f3acaa00318900bdba4b4ba26c99c666 Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Tue, 31 Jan 2023 09:50:40 -0600 Subject: [PATCH] [LinkerWrapper] Fix memory issues due to unguarded accesses to global state There were intemittent errors in the linker wrapper when using the sanitizers in parallel. First, this is because the `TempFiles` global was not guarded when creating a new file. Second, even though the `Args` list is passed as const, the internal state is mutable when adding a string. So that needs to be guarded too. Fixes https://github.com/llvm/llvm-project/issues/60437 Reviewed By: tianshilei1992 Differential Revision: https://reviews.llvm.org/D142985 --- clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 3c92d34..6981e12 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -77,6 +77,9 @@ static StringRef ExecutableName; /// Binary path for the CUDA installation. static std::string CudaBinaryPath; +/// Mutex lock to protect writes to shared TempFiles in parallel. +static std::mutex TempFilesMutex; + /// Temporary files created by the linker wrapper. static std::list> TempFiles; @@ -200,6 +203,7 @@ std::string getMainExecutable(const char *Name) { /// Get a temporary filename suitable for output. Expected createOutputFile(const Twine &Prefix, StringRef Extension) { + std::scoped_lock Lock(TempFilesMutex); SmallString<128> OutputFile; if (SaveTemps) { (Prefix + "." + Extension).toNullTerminatedStringRef(OutputFile); @@ -1047,6 +1051,7 @@ linkAndWrapDeviceFiles(SmallVectorImpl &LinkerInputFiles, return createFileError(*OutputOrErr, EC); } + std::scoped_lock Guard(ImageMtx); OffloadingImage TheImage{}; TheImage.TheImageKind = Args.hasArg(OPT_embed_bitcode) ? IMG_Bitcode : IMG_Object; @@ -1058,7 +1063,6 @@ linkAndWrapDeviceFiles(SmallVectorImpl &LinkerInputFiles, Args.MakeArgString(LinkerArgs.getLastArgValue(OPT_arch_EQ))}}; TheImage.Image = std::move(*FileOrErr); - std::lock_guard Guard(ImageMtx); Images[Kind].emplace_back(std::move(TheImage)); } return Error::success(); -- 2.7.4