Skip to content

[lldb] Don't use NamedTemporaryFile to test compiler support #151387

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
merged 1 commit into from
Jul 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions lldb/packages/Python/lldbsuite/support/temp_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""
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
"""

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)
143 changes: 71 additions & 72 deletions lldb/packages/Python/lldbsuite/test/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -876,19 +878,19 @@ 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, "-"]
p = subprocess.Popen(
cmd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
)
stdout, stderr = p.communicate("struct __attribute__((%s)) Test {};" % attr)
if attr in stderr:
return "Compiler does not support attribute %s" % (attr)
return None
with temp_file.OnDiskTempFile() as f:
cmd = [lldbplatformutil.getCompiler(), "-x", "c++", "-c", "-o", f.path, "-"]
p = subprocess.Popen(
cmd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
)
stdout, stderr = p.communicate("struct __attribute__((%s)) Test {};" % attr)
if attr in stderr:
return "Compiler does not support attribute %s" % (attr)
return None

return skipTestIfFn(compiler_doesnt_support_struct_attribute)

Expand All @@ -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)

Expand Down Expand Up @@ -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(
Expand All @@ -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"
Expand Down Expand Up @@ -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)


Expand Down
9 changes: 5 additions & 4 deletions lldb/packages/Python/lldbsuite/test/dotest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
Loading