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
788 lines
30 KiB
C++
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();
|
|
}
|