Files
TheRock/compiler/amd-llvm/lldb/unittests/Platform/PlatformDarwinTest.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

788 lines
30 KiB
C++

//===-- PlatformDarwinTest.cpp --------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "gtest/gtest.h"
#include "TestUtils.h"
#include "Plugins/Platform/MacOSX/PlatformDarwin.h"
#include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
#include "Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/TestUtilities.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/HostInfo.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Testing/Support/Error.h"
#include <memory>
#include <tuple>
using namespace lldb;
using namespace lldb_private;
struct PlatformDarwinLocateTest : public testing::Test {
protected:
void SetUp() override {
#ifdef _WIN32
GTEST_SKIP() << "PlatformDarwin tests are not supported on Windows";
#endif
std::call_once(TestUtilities::g_debugger_initialize_flag,
[]() { Debugger::Initialize(nullptr); });
ArchSpec arch("x86_64-apple-macosx-");
m_platform_sp = PlatformRemoteMacOSX::CreateInstance(true, &arch);
Platform::SetHostPlatform(m_platform_sp);
m_debugger_sp = Debugger::CreateInstance();
m_debugger_sp->GetTargetList().CreateTarget(*m_debugger_sp, "", arch,
lldb_private::eLoadDependentsNo,
m_platform_sp, m_target_sp);
ASSERT_TRUE(m_target_sp);
ASSERT_TRUE(m_platform_sp);
ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory(
"locate-scripts-from-dsym-test", m_tmp_root_dir))
<< "Failed to create test directory.";
// Create <test-root>/.dSYM/Contents/Resources
llvm::SmallString<128> dsym_resource_dir(m_tmp_root_dir);
llvm::sys::path::append(dsym_resource_dir, ".dSYM", "Contents",
"Resources");
ASSERT_FALSE(llvm::sys::fs::create_directories(dsym_resource_dir))
<< "Failed to create test dSYM root directory.";
// Create <test-root>/.dSYM/Contents/Resources/DWARF
m_tmp_dsym_dwarf_dir = dsym_resource_dir;
llvm::sys::path::append(m_tmp_dsym_dwarf_dir, "DWARF");
ASSERT_FALSE(llvm::sys::fs::create_directory(m_tmp_dsym_dwarf_dir))
<< "Failed to create test dSYM DWARF directory.";
// Create <test-root>/.dSYM/Contents/Resources/Python
m_tmp_dsym_python_dir = dsym_resource_dir;
llvm::sys::path::append(m_tmp_dsym_python_dir, "Python");
ASSERT_FALSE(llvm::sys::fs::create_directory(m_tmp_dsym_python_dir))
<< "Failed to create test dSYM Python directory.";
};
void TearDown() override {
ASSERT_FALSE(llvm::sys::fs::remove_directories(m_tmp_root_dir));
}
DebuggerSP m_debugger_sp;
PlatformSP m_platform_sp;
TargetSP m_target_sp;
/// Root directory for m_tmp_dsym_dwarf_dir and m_tmp_dsym_python_dir
llvm::SmallString<128> m_tmp_root_dir;
/// <test-root>/.dSYM/Contents/Resources/DWARF
llvm::SmallString<128> m_tmp_dsym_dwarf_dir;
/// <test-root>/.dSYM/Contents/Resources/Python
llvm::SmallString<128> m_tmp_dsym_python_dir;
SubsystemRAII<FileSystem, HostInfo, PlatformMacOSX,
MockScriptInterpreterPython>
subsystems;
};
TEST(PlatformDarwinTest, TestParseVersionBuildDir) {
llvm::VersionTuple V;
llvm::StringRef D;
std::tie(V, D) = PlatformDarwin::ParseVersionBuildDir("1.2.3 (test1)");
EXPECT_EQ(llvm::VersionTuple(1, 2, 3), V);
EXPECT_EQ("test1", D);
std::tie(V, D) = PlatformDarwin::ParseVersionBuildDir("2.3 (test2)");
EXPECT_EQ(llvm::VersionTuple(2, 3), V);
EXPECT_EQ("test2", D);
std::tie(V, D) = PlatformDarwin::ParseVersionBuildDir("3 (test3)");
EXPECT_EQ(llvm::VersionTuple(3), V);
EXPECT_EQ("test3", D);
std::tie(V, D) = PlatformDarwin::ParseVersionBuildDir("1.2.3 (test");
EXPECT_EQ(llvm::VersionTuple(1, 2, 3), V);
EXPECT_EQ("test", D);
std::tie(V, D) = PlatformDarwin::ParseVersionBuildDir("2.3.4 test");
EXPECT_EQ(llvm::VersionTuple(2, 3, 4), V);
EXPECT_EQ("", D);
std::tie(V, D) = PlatformDarwin::ParseVersionBuildDir("3.4.5");
EXPECT_EQ(llvm::VersionTuple(3, 4, 5), V);
}
TEST_F(PlatformDarwinLocateTest,
LocateExecutableScriptingResourcesFromDSYM_StripExtensions) {
// Tests that LocateExecutableScriptingResourcesFromDSYM will strip module
// names until the basename matches the Python script.
// Create dummy module file at <test-root>/TestModule.1.o.ext
FileSpec module_fspec(CreateFile("TestModule.o.1.ext", m_tmp_root_dir));
ASSERT_TRUE(module_fspec);
// Create dummy module file at
// <test-root>/.dSYM/Contents/Resources/DWARF/TestModule.o.1.ext
FileSpec dsym_module_fpec(
CreateFile("TestModule.o.1.ext", m_tmp_dsym_dwarf_dir));
ASSERT_TRUE(dsym_module_fpec);
CreateFile("TestModule.py", m_tmp_dsym_python_dir);
CreateFile("TestModule.txt", m_tmp_dsym_python_dir);
CreateFile("TestModule.sh", m_tmp_dsym_python_dir);
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fpec);
EXPECT_EQ(fspecs.size(), 1u);
EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "TestModule.py");
}
TEST_F(PlatformDarwinLocateTest,
LocateExecutableScriptingResourcesFromDSYM_ModuleNoExtension) {
// Tests case where module has no file extension.
// Create dummy module file at <test-root>/TestModule
FileSpec module_fspec(CreateFile("TestModule", m_tmp_root_dir));
ASSERT_TRUE(module_fspec);
// Create dummy module file at
// <test-root>/.dSYM/Contents/Resources/DWARF/TestModule
FileSpec dsym_module_fpec(CreateFile("TestModule", m_tmp_dsym_dwarf_dir));
ASSERT_TRUE(dsym_module_fpec);
CreateFile("TestModule.py", m_tmp_dsym_python_dir);
CreateFile("TestModule.txt", m_tmp_dsym_python_dir);
CreateFile("TestModule.sh", m_tmp_dsym_python_dir);
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fpec);
EXPECT_EQ(fspecs.size(), 1u);
EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "TestModule.py");
}
TEST_F(PlatformDarwinLocateTest,
LocateExecutableScriptingResourcesFromDSYM_StripExtension_NoMatch) {
// Tests case where stripping the module's file extensions still doesn't
// result in a match.
// Create dummy module file at <test-root>/TestModule.dylib
FileSpec module_fspec(CreateFile("TestModule.dylib", m_tmp_root_dir));
ASSERT_TRUE(module_fspec);
// Create dummy module file at
// <test-root>/.dSYM/Contents/Resources/DWARF/TestModule
FileSpec dsym_module_fpec(
CreateFile("TestModule.dylib", m_tmp_dsym_dwarf_dir));
ASSERT_TRUE(dsym_module_fpec);
CreateFile("TestModule.1.py", m_tmp_dsym_python_dir);
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fpec);
EXPECT_EQ(fspecs.size(), 0u);
}
TEST_F(PlatformDarwinLocateTest,
LocateExecutableScriptingResourcesFromDSYM_NestedDir) {
// Tests case where a nested directory within the dSYM Python directory
// contains Python scripts. LLDB shouldn't pick those.
// Create dummy module file at <test-root>/TestModule.o
FileSpec module_fspec(CreateFile("TestModule.o", m_tmp_root_dir));
ASSERT_TRUE(module_fspec);
// Create dummy module file at
// <test-root>/.dSYM/Contents/Resources/DWARF/TestModule.o
FileSpec dsym_module_fpec(CreateFile("TestModule.o", m_tmp_dsym_dwarf_dir));
ASSERT_TRUE(dsym_module_fpec);
// Create nested directory at
// <test-root>/.dSYM/Contents/Resources/Python/nested_dir
llvm::SmallString<128> nested_dir(m_tmp_dsym_python_dir);
llvm::sys::path::append(nested_dir, "nested_dir");
ASSERT_FALSE(llvm::sys::fs::create_directory(nested_dir))
<< "Failed to create test nested directory in dSYM Python directory.";
CreateFile("TestModule.py", nested_dir);
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fpec);
EXPECT_EQ(fspecs.size(), 0u);
}
TEST_F(
PlatformDarwinLocateTest,
LocateExecutableScriptingResourcesFromDSYM_KeywordInModuleNameIsKeyword) {
// Tests case where the module name has a Python reserved keyword in its name.
// That should resolve fine.
// Create dummy module file at <test-root>/TestModule_import.o
FileSpec module_fspec(CreateFile("TestModule_import.o", m_tmp_root_dir));
ASSERT_TRUE(module_fspec);
// Create dummy module file at
// <test-root>/.dSYM/Contents/Resources/DWARF/TestModule_import.o
FileSpec dsym_module_fpec(
CreateFile("TestModule_import.o", m_tmp_dsym_dwarf_dir));
ASSERT_TRUE(dsym_module_fpec);
// Keywords are not permitted in module names.
// See MockScriptInterpreterPython::IsReservedWord
CreateFile("TestModule_import.py", m_tmp_dsym_python_dir);
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fpec);
EXPECT_EQ(fspecs.size(), 1u);
EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "TestModule_import.py");
EXPECT_TRUE(ss.Empty());
}
TEST_F(PlatformDarwinLocateTest,
LocateExecutableScriptingResourcesFromDSYM_ModuleNameIsKeyword_NoMatch) {
// Tests case where the module name is a Python reserved keyword. That isn't
// supported.
// Create dummy module file at <test-root>/import
FileSpec module_fspec(CreateFile("import", m_tmp_root_dir));
ASSERT_TRUE(module_fspec);
// Create dummy module file at
// <test-root>/.dSYM/Contents/Resources/DWARF/import
FileSpec dsym_module_fpec(CreateFile("import", m_tmp_dsym_dwarf_dir));
ASSERT_TRUE(dsym_module_fpec);
// Keywords are not permitted in module names.
// See MockScriptInterpreterPython::IsReservedWord
FileSpec script_fspec(CreateFile("import.py", m_tmp_dsym_python_dir));
ASSERT_TRUE(script_fspec);
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fpec);
EXPECT_EQ(fspecs.size(), 0u);
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because 'import.py' "
"conflicts with the keyword 'import'. If you intend to have this script "
"loaded, please rename it to '_import.py' and retry.\n",
script_fspec.GetPath());
EXPECT_EQ(ss.GetString(), expected);
}
TEST_F(PlatformDarwinLocateTest,
LocateExecutableScriptingResourcesFromDSYM_ModuleNameIsKeyword_Match) {
// Tests case where the module name is a Python reserved keyword but we are
// able to match a script.
// Create dummy module file at <test-root>/import
FileSpec module_fspec(CreateFile("import", m_tmp_root_dir));
ASSERT_TRUE(module_fspec);
// Create dummy module file at
// <test-root>/.dSYM/Contents/Resources/DWARF/import
FileSpec dsym_module_fpec(CreateFile("import", m_tmp_dsym_dwarf_dir));
ASSERT_TRUE(dsym_module_fpec);
// Keywords are not permitted in module names.
// See MockScriptInterpreterPython::IsReservedWord
CreateFile("_import.py", m_tmp_dsym_python_dir);
FileSpec orig_fspec(CreateFile("import.py", m_tmp_dsym_python_dir));
ASSERT_TRUE(orig_fspec);
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fpec);
EXPECT_EQ(fspecs.size(), 1u);
EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "_import.py");
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because 'import.py' "
"conflicts with the keyword 'import'. Ignoring 'import.py' and loading "
"'_import.py' instead.\n",
orig_fspec.GetPath());
EXPECT_EQ(ss.GetString(), expected);
}
TEST_F(
PlatformDarwinLocateTest,
LocateExecutableScriptingResourcesFromDSYM_ModuleNameIsKeyword_Match_NoWarning) {
// Tests case where the module name is a Python reserved keyword but we are
// able to match a script but don't print a warning.
// Create dummy module file at <test-root>/import
FileSpec module_fspec(CreateFile("import", m_tmp_root_dir));
ASSERT_TRUE(module_fspec);
// Create dummy module file at
// <test-root>/.dSYM/Contents/Resources/DWARF/import
FileSpec dsym_module_fpec(CreateFile("import", m_tmp_dsym_dwarf_dir));
ASSERT_TRUE(dsym_module_fpec);
// Keywords are not permitted in module names.
// See MockScriptInterpreterPython::IsReservedWord
CreateFile("_import.py", m_tmp_dsym_python_dir);
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fpec);
EXPECT_EQ(fspecs.size(), 1u);
EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "_import.py");
EXPECT_TRUE(ss.GetString().empty());
}
TEST_F(
PlatformDarwinLocateTest,
LocateExecutableScriptingResourcesFromDSYM_SpecialCharactersInModuleName_NoMatch) {
// Tests case where the module name contains "special characters" that the
// Python ScriptInterpreter can't handle when importing modules.
// Create dummy module file at <test-root>/TestModule-1.1 1.o
FileSpec module_fspec(CreateFile("TestModule-1.1 1.o", m_tmp_root_dir));
ASSERT_TRUE(module_fspec);
// Create dummy module file at
// <test-root>/.dSYM/Contents/Resources/DWARF/TestModule-1.1 1.o
FileSpec dsym_module_fpec(
CreateFile("TestModule-1.1 1.o", m_tmp_dsym_dwarf_dir));
ASSERT_TRUE(dsym_module_fpec);
FileSpec script_fspec(
CreateFile("TestModule-1.1 1.py", m_tmp_dsym_python_dir));
ASSERT_TRUE(script_fspec);
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fpec);
EXPECT_EQ(fspecs.size(), 0u);
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because 'TestModule-1.1 1.py' "
"contains reserved characters. If you intend to have this script "
"loaded, please rename it to 'TestModule_1_1_1.py' and retry.\n",
script_fspec.GetPath());
EXPECT_EQ(ss.GetString(), expected);
}
TEST_F(
PlatformDarwinLocateTest,
LocateExecutableScriptingResourcesFromDSYM_SpecialCharactersInModuleName_Match_Warning) {
// Tests case where the module name contains "special characters" that the
// Python ScriptInterpreter can't handle when importing modules. LLDB can
// still match a script but it warns when two scripts conflict in naming.
// Create dummy module file at <test-root>/TestModule-1.1 1.o
FileSpec module_fspec(CreateFile("TestModule-1.1 1.o", m_tmp_root_dir));
ASSERT_TRUE(module_fspec);
// Create dummy module file at
// <test-root>/.dSYM/Contents/Resources/DWARF/TestModule-1.1 1.o
FileSpec dsym_module_fpec(
CreateFile("TestModule-1.1 1.o", m_tmp_dsym_dwarf_dir));
ASSERT_TRUE(dsym_module_fpec);
FileSpec orig_fspec(CreateFile("TestModule-1.1 1.py", m_tmp_dsym_python_dir));
ASSERT_TRUE(orig_fspec);
CreateFile("TestModule_1_1_1.py", m_tmp_dsym_python_dir);
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fpec);
EXPECT_EQ(fspecs.size(), 1u);
EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "TestModule_1_1_1.py");
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because"
" 'TestModule-1.1 1.py' contains reserved characters. Ignoring"
" 'TestModule-1.1 1.py' and loading 'TestModule_1_1_1.py' instead.\n",
orig_fspec.GetPath());
EXPECT_EQ(ss.GetString(), expected);
}
TEST_F(
PlatformDarwinLocateTest,
LocateExecutableScriptingResourcesFromDSYM_SpecialCharactersInModuleName_Match_NoWarning) {
// Tests case where the module name contains "special characters" that the
// Python ScriptInterpreter can't handle when importing modules. We can still
// match appropriately named scripts.
// Create dummy module file at <test-root>/TestModule-1.1 1.o
FileSpec module_fspec(CreateFile("TestModule-1.1 1.o", m_tmp_root_dir));
ASSERT_TRUE(module_fspec);
// Create dummy module file at
// <test-root>/.dSYM/Contents/Resources/DWARF/TestModule-1.1 1.o
FileSpec dsym_module_fpec(
CreateFile("TestModule-1.1 1.o", m_tmp_dsym_dwarf_dir));
ASSERT_TRUE(dsym_module_fpec);
CreateFile("TestModule_1_1_1.py", m_tmp_dsym_python_dir);
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fpec);
EXPECT_EQ(fspecs.size(), 1u);
EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "TestModule_1_1_1.py");
EXPECT_TRUE(ss.GetString().empty());
}
TEST_F(
PlatformDarwinLocateTest,
LocateExecutableScriptingResourcesFromDSYM_ModuleNameIsKeywordAfterReplacement) {
// Test case where the module name contains "special characters" but after
// LLDB replaces those the filename is still a keyword. We ensure this by a
// special case in MockScriptInterpreterPython::IsReservedWord.
// Create dummy module file at <test-root>/mykeyword-1.1 1.o
FileSpec module_fspec(CreateFile("mykeyword-1.1 1.o", m_tmp_root_dir));
ASSERT_TRUE(module_fspec);
// Create dummy module file at
// <test-root>/.dSYM/Contents/Resources/DWARF/mykeyword-1.1 1.o
FileSpec dsym_module_fpec(
CreateFile("mykeyword-1.1 1.o", m_tmp_dsym_dwarf_dir));
ASSERT_TRUE(dsym_module_fpec);
CreateFile("mykeyword-1.1 1.py", m_tmp_dsym_python_dir);
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fpec);
EXPECT_EQ(fspecs.size(), 0u);
EXPECT_TRUE(
ss.GetString().contains("conflicts with the keyword 'mykeyword_1_1_1'"));
}
TEST_F(
PlatformDarwinLocateTest,
LocateExecutableScriptingResourcesFromDSYM_ModuleNameIsKeywordAfterReplacement_Match_Warning) {
// Like
// LocateExecutableScriptingResourcesFromDSYM_ModuleNameIsKeywordAfterReplacement
// but we place a script with all the replacement characters into the module
// directory so LLDB loads it. That will still produce a warning.
// Create dummy module file at <test-root>/mykeyword-1.1 1.o
FileSpec module_fspec(CreateFile("mykeyword-1.1 1.o", m_tmp_root_dir));
ASSERT_TRUE(module_fspec);
// Create dummy module file at
// <test-root>/.dSYM/Contents/Resources/DWARF/mykeyword-1.1 1.o
FileSpec dsym_module_fpec(
CreateFile("mykeyword-1.1 1.o", m_tmp_dsym_dwarf_dir));
ASSERT_TRUE(dsym_module_fpec);
CreateFile("mykeyword-1.1 1.py", m_tmp_dsym_python_dir);
CreateFile("_mykeyword_1_1_1.py", m_tmp_dsym_python_dir);
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fpec);
EXPECT_EQ(fspecs.size(), 1u);
EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "_mykeyword_1_1_1.py");
EXPECT_TRUE(ss.GetString().contains("Ignoring 'mykeyword-1.1 1.py' and "
"loading '_mykeyword_1_1_1.py' instead"));
}
TEST_F(
PlatformDarwinLocateTest,
LocateExecutableScriptingResourcesFromDSYM_ModuleNameIsKeywordAfterReplacement_Match_NoWarning) {
// Like
// LocateExecutableScriptingResourcesFromDSYM_ModuleNameIsKeywordAfterReplacement_Match_Warning
// but we place a script with all the replacement characters into the module
// directory so LLDB loads it (but no script that matches the original module
// name, and hence generates no warning).
// Create dummy module file at <test-root>/mykeyword-1.1 1.o
FileSpec module_fspec(CreateFile("mykeyword-1.1 1.o", m_tmp_root_dir));
ASSERT_TRUE(module_fspec);
// Create dummy module file at
// <test-root>/.dSYM/Contents/Resources/DWARF/mykeyword-1.1 1.o
FileSpec dsym_module_fpec(
CreateFile("mykeyword-1.1 1.o", m_tmp_dsym_dwarf_dir));
ASSERT_TRUE(dsym_module_fpec);
CreateFile("_mykeyword_1_1_1.py", m_tmp_dsym_python_dir);
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fpec);
EXPECT_EQ(fspecs.size(), 1u);
EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "_mykeyword_1_1_1.py");
EXPECT_TRUE(ss.Empty());
}
TEST_F(PlatformDarwinLocateTest,
LocateExecutableScriptingResourcesFromDSYM_AutoLoadScriptsForModule) {
// Test that the LocateExecutableScriptingResourcesFromDSYM API respects the
// target.auto-load-scripts-for-modules setting.
m_target_sp->SetLoadScriptFromSymbolFile(eLoadScriptFromSymFileTrusted);
auto setup_module = [this](llvm::StringRef module_name) {
FileSpec module_fspec(
CreateFile(llvm::formatv("{0}.o", module_name).str(), m_tmp_root_dir));
EXPECT_TRUE(module_fspec);
FileSpec dsym_module_fpec(CreateFile(
llvm::formatv("{0}.o", module_name).str(), m_tmp_dsym_dwarf_dir));
EXPECT_TRUE(dsym_module_fpec);
FileSpec script_fspec(CreateFile(llvm::formatv("{0}.py", module_name).str(),
m_tmp_dsym_python_dir));
return std::pair{script_fspec, dsym_module_fpec};
};
auto [script_false_fspec, dsym_module_false_fspec] =
setup_module("ModuleFalse");
m_target_sp->SetAutoLoadScriptsForModule("ModuleFalse",
eLoadScriptFromSymFileFalse);
auto [script_true_fspec, dsym_module_true_fspec] = setup_module("ModuleTrue");
m_target_sp->SetAutoLoadScriptsForModule("ModuleTrue",
eLoadScriptFromSymFileTrue);
auto [script_warn_fspec, dsym_module_warn_fspec] = setup_module("ModuleWarn");
m_target_sp->SetAutoLoadScriptsForModule("ModuleWarn",
eLoadScriptFromSymFileWarn);
auto [script_trusted_fspec, dsym_module_trusted_fspec] =
setup_module("ModuleTrusted");
m_target_sp->SetAutoLoadScriptsForModule("ModuleTrusted",
eLoadScriptFromSymFileTrusted);
auto [script_another_true_fspec, dsym_module_another_true_fspec] =
setup_module("ModuleAnotherTrue");
m_target_sp->SetAutoLoadScriptsForModule("ModuleAnotherTrue",
eLoadScriptFromSymFileTrue);
auto [script_default_fspec, dsym_module_default_fspec] =
setup_module("ModuleDefault");
{
StreamString ss;
auto fspecs =
std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, script_false_fspec, *m_target_sp, dsym_module_false_fspec);
ASSERT_EQ(fspecs.size(), 1u);
ASSERT_TRUE(fspecs.contains(script_false_fspec));
EXPECT_EQ(fspecs[script_false_fspec], eLoadScriptFromSymFileFalse);
}
{
StreamString ss;
auto fspecs =
std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, script_true_fspec, *m_target_sp, dsym_module_true_fspec);
ASSERT_EQ(fspecs.size(), 1u);
ASSERT_TRUE(fspecs.contains(script_true_fspec));
EXPECT_EQ(fspecs[script_true_fspec], eLoadScriptFromSymFileTrue);
}
{
StreamString ss;
auto fspecs =
std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, script_warn_fspec, *m_target_sp, dsym_module_warn_fspec);
ASSERT_EQ(fspecs.size(), 1u);
ASSERT_TRUE(fspecs.contains(script_warn_fspec));
EXPECT_EQ(fspecs[script_warn_fspec], eLoadScriptFromSymFileWarn);
}
{
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, script_trusted_fspec, *m_target_sp,
dsym_module_trusted_fspec);
ASSERT_EQ(fspecs.size(), 1u);
ASSERT_TRUE(fspecs.contains(script_trusted_fspec));
EXPECT_EQ(fspecs[script_trusted_fspec], eLoadScriptFromSymFileTrusted);
}
{
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, script_another_true_fspec, *m_target_sp,
dsym_module_another_true_fspec);
ASSERT_EQ(fspecs.size(), 1u);
ASSERT_TRUE(fspecs.contains(script_another_true_fspec));
EXPECT_EQ(fspecs[script_another_true_fspec], eLoadScriptFromSymFileTrue);
}
{
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, script_default_fspec, *m_target_sp,
dsym_module_default_fspec);
ASSERT_EQ(fspecs.size(), 1u);
ASSERT_TRUE(fspecs.contains(script_default_fspec));
EXPECT_EQ(fspecs[script_default_fspec], eLoadScriptFromSymFileTrusted);
}
}
TEST_F(PlatformDarwinLocateTest,
LocateExecutableScriptingResourcesFromDSYM_AutoLoadUsesModuleName) {
// Test that the auto-load-scripts-for-modules setting uses the module
// name (not the sanitized script name) for lookup. The module is named
// "TestModule.1" (with a dot), and the script is "TestModule_1.py"
// (sanitized). Setting "TestModule_1=true" should NOT affect loading
// because the lookup key should be "TestModule.1".
// Create dummy module file at <test-root>/TestModule.1.o
FileSpec module_fspec(CreateFile("TestModule.1.o", m_tmp_root_dir));
ASSERT_TRUE(module_fspec);
FileSpec dsym_module_fspec(
CreateFile("TestModule.1.o", m_tmp_dsym_dwarf_dir));
ASSERT_TRUE(dsym_module_fspec);
CreateFile("TestModule_1.py", m_tmp_dsym_python_dir);
m_target_sp->SetLoadScriptFromSymbolFile(eLoadScriptFromSymFileFalse);
// Setting the sanitized script name should NOT cause loading.
m_target_sp->SetAutoLoadScriptsForModule("TestModule_1",
eLoadScriptFromSymFileTrue);
{
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fspec);
ASSERT_EQ(fspecs.size(), 1u);
EXPECT_EQ(fspecs.begin()->second, eLoadScriptFromSymFileFalse);
}
// Now set the actual module name. This should override the default.
m_target_sp->SetAutoLoadScriptsForModule("TestModule.1",
eLoadScriptFromSymFileTrue);
{
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fspec);
ASSERT_EQ(fspecs.size(), 1u);
EXPECT_EQ(fspecs.begin()->second, eLoadScriptFromSymFileTrue);
}
}
struct SpecialCharTestCase {
char special_char;
char replacement;
};
struct PlatformDarwinLocateWithSpecialCharsTestFixture
: public testing::WithParamInterface<SpecialCharTestCase>,
public PlatformDarwinLocateTest {};
TEST_P(PlatformDarwinLocateWithSpecialCharsTestFixture,
LocateExecutableScriptingResourcesFromDSYM_SpecialCharacters) {
// Tests the various special characters that `ScriptInterpreterPython`
// disallows in module names.
auto [special_char, replacement] = GetParam();
std::string module_name = llvm::formatv("TestModule{0}.o", special_char);
std::string script_name = llvm::formatv("TestModule{0}.py", special_char);
std::string recommended_script_name =
llvm::formatv("TestModule{0}.py", replacement);
// Create dummy module file at <test-root>/<module-name>
FileSpec module_fspec(CreateFile(module_name, m_tmp_root_dir));
ASSERT_TRUE(module_fspec);
// Create dummy module file at
// <test-root>/.dSYM/Contents/Resources/DWARF/<module-name>
FileSpec dsym_module_fpec(CreateFile(module_name, m_tmp_dsym_dwarf_dir));
ASSERT_TRUE(dsym_module_fpec);
CreateFile(script_name, m_tmp_dsym_python_dir);
StreamString ss;
auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->LocateExecutableScriptingResourcesFromDSYM(
ss, module_fspec, *m_target_sp, dsym_module_fpec);
EXPECT_EQ(fspecs.size(), 0u);
std::string expected =
llvm::formatv("please rename it to '{0}'", recommended_script_name);
EXPECT_TRUE(ss.GetString().contains(expected));
}
INSTANTIATE_TEST_SUITE_P(PlatformDarwinLocateWithSpecialCharsTest,
PlatformDarwinLocateWithSpecialCharsTestFixture,
testing::ValuesIn(std::vector<SpecialCharTestCase>{
{' ', '_'}, {'.', '_'}, {'-', '_'}, {'+', 'x'}}));
TEST_F(PlatformDarwinLocateTest, GetSafeAutoLoadPaths) {
// Tests PlatformDarwin::GetSafeAutoLoadPaths returns a path into the SDK on
// Darwin platforms.
auto paths_or_err = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
->GetSafeAutoLoadPaths(*m_target_sp);
ASSERT_THAT_EXPECTED(paths_or_err, llvm::Succeeded());
ASSERT_EQ(paths_or_err->GetSize(), 1u);
// The returned path should be $SDKROOT/usr/share/lldb.
FileSpec path = paths_or_err->GetFileSpecAtIndex(0);
EXPECT_TRUE(llvm::StringRef(path.GetPath()).ends_with("/usr/share/lldb"))
<< "Unexpected path: " << path.GetPath();
}