https://github.com/JDevlieghere updated 
https://github.com/llvm/llvm-project/pull/151387

>From 97435049d503045f22e169825244c944f31968c7 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jo...@devlieghere.com>
Date: Wed, 30 Jul 2025 13:19:50 -0700
Subject: [PATCH] [lldb] Don't use NamedTemporaryFile to test compiler support

You cannot use a NamedTempFile with an external process because it may
not be flushed to disk.  The safest and most portable approach is to
close the file, call the other process and then unlink the file
manually.

Presumably this works fine on Linux, but it fails on Darwin when
targeting remote-linux.

See https://bugs.python.org/issue29573
---
 .../Python/lldbsuite/support/temp_file.py     |  26 ++++
 .../Python/lldbsuite/test/decorators.py       | 121 +++++++++---------
 lldb/packages/Python/lldbsuite/test/dotest.py |   9 +-
 3 files changed, 91 insertions(+), 65 deletions(-)
 create mode 100644 lldb/packages/Python/lldbsuite/support/temp_file.py

diff --git a/lldb/packages/Python/lldbsuite/support/temp_file.py 
b/lldb/packages/Python/lldbsuite/support/temp_file.py
new file mode 100644
index 0000000000000..3ea0683ec87d0
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/support/temp_file.py
@@ -0,0 +1,26 @@
+"""
+Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+See https://llvm.org/LICENSE.txt for license information.
+SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+Prepares language bindings for LLDB build process.  Run with --help
+to see a description of the supported command line arguments.
+"""
+
+import os
+import tempfile
+
+
+class OnDiskTempFile:
+    def __init__(self, delete=True):
+        self.path = None
+
+    def __enter__(self):
+        fd, path = tempfile.mkstemp()
+        os.close(fd)
+        self.path = path
+        return self
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        if os.path.exists(self.path):
+            os.remove(self.path)
diff --git a/lldb/packages/Python/lldbsuite/test/decorators.py 
b/lldb/packages/Python/lldbsuite/test/decorators.py
index a5f58373ede75..acf9ea1a1f85f 100644
--- a/lldb/packages/Python/lldbsuite/test/decorators.py
+++ b/lldb/packages/Python/lldbsuite/test/decorators.py
@@ -20,6 +20,7 @@
 from . import test_categories
 from . import lldbtest_config
 from lldbsuite.support import funcutils
+from lldbsuite.support import temp_file
 from lldbsuite.test import lldbplatform
 from lldbsuite.test import lldbplatformutil
 
@@ -94,22 +95,23 @@ def _match_decorator_property(expected, actual):
 
 
 def _compiler_supports(
-    compiler, flag, source="int main() {}", 
output_file=tempfile.NamedTemporaryFile()
+    compiler, flag, source="int main() {}", 
output_file=temp_file.OnDiskTempFile()
 ):
     """Test whether the compiler supports the given flag."""
-    if platform.system() == "Darwin":
-        compiler = "xcrun " + compiler
-    try:
-        cmd = "echo '%s' | %s %s -x c -o %s -" % (
-            source,
-            compiler,
-            flag,
-            output_file.name,
-        )
-        subprocess.check_call(cmd, shell=True)
-    except subprocess.CalledProcessError:
-        return False
-    return True
+    with output_file:
+        if platform.system() == "Darwin":
+            compiler = "xcrun " + compiler
+        try:
+            cmd = "echo '%s' | %s %s -x c -o %s -" % (
+                source,
+                compiler,
+                flag,
+                output_file.path,
+            )
+            subprocess.check_call(cmd, shell=True)
+        except subprocess.CalledProcessError:
+            return False
+        return True
 
 
 def expectedFailureIf(condition, bugnumber=None):
@@ -876,8 +878,8 @@ def skipUnlessSupportedTypeAttribute(attr):
 
     def compiler_doesnt_support_struct_attribute():
         compiler_path = lldbplatformutil.getCompiler()
-        f = tempfile.NamedTemporaryFile()
-        cmd = [lldbplatformutil.getCompiler(), "-x", "c++", "-c", "-o", 
f.name, "-"]
+        f = temp_file.OnDiskTempFile()
+        cmd = [lldbplatformutil.getCompiler(), "-x", "c++", "-c", "-o", 
f.path, "-"]
         p = subprocess.Popen(
             cmd,
             stdin=subprocess.PIPE,
@@ -902,21 +904,21 @@ def is_compiler_clang_with_call_site_info():
         if not compiler.startswith("clang"):
             return "Test requires clang as compiler"
 
-        f = tempfile.NamedTemporaryFile()
-        cmd = (
-            "echo 'int main() {}' | "
-            "%s -g -glldb -O1 -S -emit-llvm -x c -o %s -" % (compiler_path, 
f.name)
-        )
-        if os.popen(cmd).close() is not None:
-            return "Compiler can't compile with call site info enabled"
+        with temp_file.OnDiskTempFile() as f:
+            cmd = (
+                "echo 'int main() {}' | "
+                "%s -g -glldb -O1 -S -emit-llvm -x c -o %s -" % 
(compiler_path, f.path)
+            )
+            if os.popen(cmd).close() is not None:
+                return "Compiler can't compile with call site info enabled"
 
-        with open(f.name, "r") as ir_output_file:
-            buf = ir_output_file.read()
+            with open(f.path, "r") as ir_output_file:
+                buf = ir_output_file.read()
 
-        if "DIFlagAllCallsDescribed" not in buf:
-            return "Compiler did not introduce DIFlagAllCallsDescribed IR flag"
+            if "DIFlagAllCallsDescribed" not in buf:
+                return "Compiler did not introduce DIFlagAllCallsDescribed IR 
flag"
 
-        return None
+            return None
 
     return skipTestIfFn(is_compiler_clang_with_call_site_info)(func)
 
@@ -957,7 +959,7 @@ def is_compiler_clang_with_ubsan():
             )
 
         # We need to write out the object into a named temp file for 
inspection.
-        outputf = tempfile.NamedTemporaryFile()
+        outputf = temp_file.OnDiskTempFile()
 
         # Try to compile with ubsan turned on.
         if not _compiler_supports(
@@ -969,7 +971,7 @@ def is_compiler_clang_with_ubsan():
             return "Compiler cannot compile with -fsanitize=undefined"
 
         # Check that we actually see ubsan instrumentation in the binary.
-        cmd = "nm %s" % outputf.name
+        cmd = "nm %s" % outputf.path
         with os.popen(cmd) as nm_output:
             if "___ubsan_handle_divrem_overflow" not in nm_output.read():
                 return "Division by zero instrumentation is missing"
@@ -1037,40 +1039,37 @@ def skipUnlessAArch64MTELinuxCompiler(func):
 
     def is_toolchain_with_mte():
         compiler_path = lldbplatformutil.getCompiler()
-        f = tempfile.NamedTemporaryFile(delete=False)
-        if lldbplatformutil.getPlatform() == "windows":
-            return "MTE tests are not compatible with 'windows'"
-
-        # Note hostos may be Windows.
-        f.close()
+        with temp_file.OnDiskTempFile() as f:
+            if lldbplatformutil.getPlatform() == "windows":
+                return "MTE tests are not compatible with 'windows'"
+
+            cmd = f"{compiler_path} -x c -o {f.path} -"
+            if (
+                subprocess.run(
+                    cmd, shell=True, input="int main() {}".encode()
+                ).returncode
+                != 0
+            ):
+                # Cannot compile at all, don't skip the test
+                # so that we report the broken compiler normally.
+                return None
 
-        cmd = f"{compiler_path} -x c -o {f.name} -"
-        if (
-            subprocess.run(cmd, shell=True, input="int main() 
{}".encode()).returncode
-            != 0
-        ):
-            os.remove(f.name)
-            # Cannot compile at all, don't skip the test
-            # so that we report the broken compiler normally.
+            # We need the Linux headers and ACLE MTE intrinsics
+            test_src = """
+                #include <asm/hwcap.h>
+                #include <arm_acle.h>
+                #ifndef HWCAP2_MTE
+                #error
+                #endif
+                int main() {
+                    void* ptr = __arm_mte_create_random_tag((void*)(0), 0);
+                }"""
+            cmd = f"{compiler_path} -march=armv8.5-a+memtag -x c -o {f.path} -"
+            res = subprocess.run(cmd, shell=True, input=test_src.encode())
+            if res.returncode != 0:
+                return "Toolchain does not support MTE"
             return None
 
-        # We need the Linux headers and ACLE MTE intrinsics
-        test_src = """
-            #include <asm/hwcap.h>
-            #include <arm_acle.h>
-            #ifndef HWCAP2_MTE
-            #error
-            #endif
-            int main() {
-                void* ptr = __arm_mte_create_random_tag((void*)(0), 0);
-            }"""
-        cmd = f"{compiler_path} -march=armv8.5-a+memtag -x c -o {f.name} -"
-        res = subprocess.run(cmd, shell=True, input=test_src.encode())
-        os.remove(f.name)
-        if res.returncode != 0:
-            return "Toolchain does not support MTE"
-        return None
-
     return skipTestIfFn(is_toolchain_with_mte)(func)
 
 
diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py 
b/lldb/packages/Python/lldbsuite/test/dotest.py
index 24236e779e51d..0dffa7a2c6c7b 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest.py
@@ -43,6 +43,7 @@
 from . import test_categories
 from . import test_result
 from ..support import seven
+from ..support import temp_file
 
 
 def is_exe(fpath):
@@ -780,8 +781,8 @@ def canRunLibcxxTests():
         return True, "libc++ always present"
 
     if platform == "linux":
-        with tempfile.NamedTemporaryFile() as f:
-            cmd = [configuration.compiler, "-xc++", "-stdlib=libc++", "-o", 
f.name, "-"]
+        with temp_file.OnDiskTempFile() as f:
+            cmd = [configuration.compiler, "-xc++", "-stdlib=libc++", "-o", 
f.path, "-"]
             p = subprocess.Popen(
                 cmd,
                 stdin=subprocess.PIPE,
@@ -840,8 +841,8 @@ def canRunMsvcStlTests():
     if platform != "windows":
         return False, f"Don't know how to build with MSVC's STL on {platform}"
 
-    with tempfile.NamedTemporaryFile() as f:
-        cmd = [configuration.compiler, "-xc++", "-o", f.name, "-E", "-"]
+    with temp_file.OnDiskTempFile() as f:
+        cmd = [configuration.compiler, "-xc++", "-o", f.path, "-E", "-"]
         p = subprocess.Popen(
             cmd,
             stdin=subprocess.PIPE,

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to