[lldb] Remove the global platform list

This patch moves the platform creation and selection logic into the
per-debugger platform lists. I've tried to keep functional changes to a
minimum -- the main (only) observable difference in this change is that
APIs, which select a platform by name (e.g.,
Debugger::SetCurrentPlatform) will not automatically pick up a platform
associated with another debugger (or no debugger at all).

I've also added several tests for this functionality -- one of the
pleasant consequences of the debugger isolation is that it is now
possible to test the platform selection and creation logic.

This is a product of the discussion at
<https://discourse.llvm.org/t/multiple-platforms-with-the-same-name/59594>.

Differential Revision: https://reviews.llvm.org/D120810
This commit is contained in:
Pavel Labath
2022-02-25 14:47:27 +01:00
parent 0f622bd281
commit ffb9429b6f
18 changed files with 288 additions and 190 deletions

View File

@@ -94,20 +94,11 @@ public:
/// attaching to processes unless another platform is specified.
static lldb::PlatformSP GetHostPlatform();
static lldb::PlatformSP
GetPlatformForArchitecture(const ArchSpec &arch, ArchSpec *platform_arch_ptr);
static const char *GetHostPlatformName();
static void SetHostPlatform(const lldb::PlatformSP &platform_sp);
// Find an existing platform plug-in by name
static lldb::PlatformSP Find(ConstString name);
static lldb::PlatformSP Create(ConstString name, Status &error);
static lldb::PlatformSP Create(const ArchSpec &arch,
ArchSpec *platform_arch_ptr, Status &error);
static lldb::PlatformSP Create(llvm::StringRef name);
/// Augments the triple either with information from platform or the host
/// system (if platform is null).
@@ -1015,6 +1006,14 @@ public:
}
}
lldb::PlatformSP GetOrCreate(llvm::StringRef name);
lldb::PlatformSP GetOrCreate(const ArchSpec &arch, ArchSpec *platform_arch_ptr,
Status &error);
lldb::PlatformSP GetOrCreate(const ArchSpec &arch,
ArchSpec *platform_arch_ptr);
lldb::PlatformSP Create(llvm::StringRef name);
protected:
typedef std::vector<lldb::PlatformSP> collection;
mutable std::recursive_mutex m_mutex;

View File

@@ -1428,21 +1428,11 @@ SBError SBDebugger::SetCurrentPlatform(const char *platform_name_cstr) {
SBError sb_error;
if (m_opaque_sp) {
if (platform_name_cstr && platform_name_cstr[0]) {
ConstString platform_name(platform_name_cstr);
PlatformSP platform_sp(Platform::Find(platform_name));
if (platform_sp) {
// Already have a platform with this name, just select it
m_opaque_sp->GetPlatformList().SetSelectedPlatform(platform_sp);
} else {
// We don't have a platform by this name yet, create one
platform_sp = Platform::Create(platform_name, sb_error.ref());
if (platform_sp) {
// We created the platform, now append and select it
bool make_selected = true;
m_opaque_sp->GetPlatformList().Append(platform_sp, make_selected);
}
}
PlatformList &platforms = m_opaque_sp->GetPlatformList();
if (PlatformSP platform_sp = platforms.GetOrCreate(platform_name_cstr))
platforms.SetSelectedPlatform(platform_sp);
else
sb_error.ref().SetErrorString("platform not found");
} else {
sb_error.ref().SetErrorString("invalid platform name");
}

View File

@@ -293,9 +293,7 @@ SBPlatform::SBPlatform() { LLDB_INSTRUMENT_VA(this); }
SBPlatform::SBPlatform(const char *platform_name) {
LLDB_INSTRUMENT_VA(this, platform_name);
Status error;
if (platform_name && platform_name[0])
m_opaque_sp = Platform::Create(ConstString(platform_name), error);
m_opaque_sp = Platform::Create(platform_name);
}
SBPlatform::SBPlatform(const SBPlatform &rhs) {

View File

@@ -18,10 +18,17 @@ using namespace lldb_private;
PlatformSP OptionGroupPlatform::CreatePlatformWithOptions(
CommandInterpreter &interpreter, const ArchSpec &arch, bool make_selected,
Status &error, ArchSpec &platform_arch) const {
PlatformList &platforms = interpreter.GetDebugger().GetPlatformList();
PlatformSP platform_sp;
if (!m_platform_name.empty()) {
platform_sp = Platform::Create(ConstString(m_platform_name.c_str()), error);
platform_sp = platforms.Create(m_platform_name);
if (!platform_sp) {
error.SetErrorStringWithFormatv(
"unable to find a plug-in for the platform named \"{0}\"",
m_platform_name);
}
if (platform_sp) {
if (platform_arch.IsValid() &&
!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) {
@@ -33,12 +40,14 @@ PlatformSP OptionGroupPlatform::CreatePlatformWithOptions(
}
}
} else if (arch.IsValid()) {
platform_sp = Platform::Create(arch, &platform_arch, error);
platform_sp = platforms.GetOrCreate(arch, &platform_arch, error);
if (platform_sp)
platforms.Append(platform_sp, make_selected);
}
if (platform_sp) {
interpreter.GetDebugger().GetPlatformList().Append(platform_sp,
make_selected);
if (make_selected)
platforms.SetSelectedPlatform(platform_sp);
if (!m_os_version.empty())
platform_sp->SetOSVersion(m_os_version);

View File

@@ -511,8 +511,9 @@ DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel(Process *process,
m_kext_summary_header(), m_known_kexts(), m_mutex(),
m_break_id(LLDB_INVALID_BREAK_ID) {
Status error;
PlatformSP platform_sp(Platform::Create(
ConstString(PlatformDarwinKernel::GetPluginNameStatic()), error));
PlatformSP platform_sp =
process->GetTarget().GetDebugger().GetPlatformList().Create(
PlatformDarwinKernel::GetPluginNameStatic());
if (platform_sp.get())
process->GetTarget().SetPlatform(platform_sp);
}

View File

@@ -7,5 +7,6 @@ add_lldb_library(lldbPluginPlatformPOSIX
lldbHost
lldbInterpreter
lldbTarget
lldbPluginPlatformGDB
lldbPluginTypeSystemClang
)

View File

@@ -8,6 +8,7 @@
#include "PlatformPOSIX.h"
#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
@@ -307,7 +308,8 @@ Status PlatformPOSIX::ConnectRemote(Args &args) {
} else {
if (!m_remote_platform_sp)
m_remote_platform_sp =
Platform::Create(ConstString("remote-gdb-server"), error);
platform_gdb_server::PlatformRemoteGDBServer::CreateInstance(
/*force=*/true, nullptr);
if (m_remote_platform_sp && error.Success())
error = m_remote_platform_sp->ConnectRemote(args);

View File

@@ -6,6 +6,7 @@ add_lldb_library(lldbPluginPlatformWindows PLUGIN
lldbCore
lldbHost
lldbTarget
lldbPluginPlatformGDB
LINK_COMPONENTS
Support

View File

@@ -14,6 +14,8 @@
#include <winsock2.h>
#endif
#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointSite.h"
#include "lldb/Core/Debugger.h"
@@ -28,8 +30,6 @@
#include "lldb/Target/Process.h"
#include "lldb/Utility/Status.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/Support/ConvertUTF.h"
@@ -140,7 +140,8 @@ Status PlatformWindows::ConnectRemote(Args &args) {
} else {
if (!m_remote_platform_sp)
m_remote_platform_sp =
Platform::Create(ConstString("remote-gdb-server"), error);
platform_gdb_server::PlatformRemoteGDBServer::CreateInstance(
/*force=*/true, nullptr);
if (m_remote_platform_sp) {
if (error.Success()) {

View File

@@ -7,4 +7,5 @@ add_lldb_library(lldbPluginPlatformGDB PLUGIN
lldbHost
lldbTarget
lldbPluginProcessUtility
lldbPluginProcessGDBRemote
)

View File

@@ -49,8 +49,6 @@
using namespace lldb;
using namespace lldb_private;
static uint32_t g_initialize_count = 0;
// Use a singleton function for g_local_platform_sp to avoid init constructors
// since LLDB is often part of a shared library
static PlatformSP &GetHostPlatformSP() {
@@ -135,26 +133,9 @@ void PlatformProperties::SetDefaultModuleCacheDirectory(
/// or attaching to processes unless another platform is specified.
PlatformSP Platform::GetHostPlatform() { return GetHostPlatformSP(); }
static std::vector<PlatformSP> &GetPlatformList() {
static std::vector<PlatformSP> g_platform_list;
return g_platform_list;
}
void Platform::Initialize() {}
static std::recursive_mutex &GetPlatformListMutex() {
static std::recursive_mutex g_mutex;
return g_mutex;
}
void Platform::Initialize() { g_initialize_count++; }
void Platform::Terminate() {
if (g_initialize_count > 0) {
if (--g_initialize_count == 0) {
std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
GetPlatformList().clear();
}
}
}
void Platform::Terminate() {}
PlatformProperties &Platform::GetGlobalPlatformProperties() {
static PlatformProperties g_settings;
@@ -165,11 +146,6 @@ void Platform::SetHostPlatform(const lldb::PlatformSP &platform_sp) {
// The native platform should use its static void Platform::Initialize()
// function to register itself as the native platform.
GetHostPlatformSP() = platform_sp;
if (platform_sp) {
std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
GetPlatformList().push_back(platform_sp);
}
}
Status Platform::GetFileWithUUID(const FileSpec &platform_file,
@@ -272,108 +248,15 @@ bool Platform::GetModuleSpec(const FileSpec &module_file_spec,
module_spec);
}
PlatformSP Platform::Find(ConstString name) {
if (name) {
static ConstString g_host_platform_name("host");
if (name == g_host_platform_name)
return GetHostPlatform();
std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
for (const auto &platform_sp : GetPlatformList()) {
if (platform_sp->GetName() == name.GetStringRef())
return platform_sp;
}
}
return PlatformSP();
}
PlatformSP Platform::Create(ConstString name, Status &error) {
PlatformCreateInstance create_callback = nullptr;
PlatformSP Platform::Create(llvm::StringRef name) {
lldb::PlatformSP platform_sp;
if (name) {
static ConstString g_host_platform_name("host");
if (name == g_host_platform_name)
return GetHostPlatform();
if (name == GetHostPlatformName())
return GetHostPlatform();
create_callback = PluginManager::GetPlatformCreateCallbackForPluginName(
name.GetStringRef());
if (create_callback)
platform_sp = create_callback(true, nullptr);
else
error.SetErrorStringWithFormat(
"unable to find a plug-in for the platform named \"%s\"",
name.GetCString());
} else
error.SetErrorString("invalid platform name");
if (platform_sp) {
std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
GetPlatformList().push_back(platform_sp);
}
return platform_sp;
}
PlatformSP Platform::Create(const ArchSpec &arch, ArchSpec *platform_arch_ptr,
Status &error) {
lldb::PlatformSP platform_sp;
if (arch.IsValid()) {
// Scope for locker
{
// First try exact arch matches across all platforms already created
std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
for (const auto &platform_sp : GetPlatformList()) {
if (platform_sp->IsCompatibleArchitecture(arch, true,
platform_arch_ptr))
return platform_sp;
}
// Next try compatible arch matches across all platforms already created
for (const auto &platform_sp : GetPlatformList()) {
if (platform_sp->IsCompatibleArchitecture(arch, false,
platform_arch_ptr))
return platform_sp;
}
}
PlatformCreateInstance create_callback;
// First try exact arch matches across all platform plug-ins
uint32_t idx;
for (idx = 0; (create_callback =
PluginManager::GetPlatformCreateCallbackAtIndex(idx));
++idx) {
if (create_callback) {
platform_sp = create_callback(false, &arch);
if (platform_sp &&
platform_sp->IsCompatibleArchitecture(arch, true,
platform_arch_ptr)) {
std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
GetPlatformList().push_back(platform_sp);
return platform_sp;
}
}
}
// Next try compatible arch matches across all platform plug-ins
for (idx = 0; (create_callback =
PluginManager::GetPlatformCreateCallbackAtIndex(idx));
++idx) {
if (create_callback) {
platform_sp = create_callback(false, &arch);
if (platform_sp &&
platform_sp->IsCompatibleArchitecture(arch, false,
platform_arch_ptr)) {
std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
GetPlatformList().push_back(platform_sp);
return platform_sp;
}
}
}
} else
error.SetErrorString("invalid platform name");
if (platform_arch_ptr)
platform_arch_ptr->Clear();
platform_sp.reset();
return platform_sp;
if (PlatformCreateInstance create_callback =
PluginManager::GetPlatformCreateCallbackForPluginName(name))
return create_callback(true, nullptr);
return nullptr;
}
ArchSpec Platform::GetAugmentedArchSpec(Platform *platform, llvm::StringRef triple) {
@@ -1200,16 +1083,6 @@ lldb::ProcessSP Platform::DebugProcess(ProcessLaunchInfo &launch_info,
return process_sp;
}
lldb::PlatformSP
Platform::GetPlatformForArchitecture(const ArchSpec &arch,
ArchSpec *platform_arch_ptr) {
lldb::PlatformSP platform_sp;
Status error;
if (arch.IsValid())
platform_sp = Platform::Create(arch, platform_arch_ptr, error);
return platform_sp;
}
std::vector<ArchSpec>
Platform::CreateArchList(llvm::ArrayRef<llvm::Triple::ArchType> archs,
llvm::Triple::OSType os) {
@@ -2005,3 +1878,72 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target,
CompilerType Platform::GetSiginfoType(const llvm::Triple& triple) {
return CompilerType();
}
PlatformSP PlatformList::GetOrCreate(llvm::StringRef name) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
for (const PlatformSP &platform_sp : m_platforms) {
if (platform_sp->GetName() == name)
return platform_sp;
}
return Create(name);
}
PlatformSP PlatformList::GetOrCreate(const ArchSpec &arch,
ArchSpec *platform_arch_ptr,
Status &error) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
// First try exact arch matches across all platforms already created
for (const auto &platform_sp : m_platforms) {
if (platform_sp->IsCompatibleArchitecture(arch, true, platform_arch_ptr))
return platform_sp;
}
// Next try compatible arch matches across all platforms already created
for (const auto &platform_sp : m_platforms) {
if (platform_sp->IsCompatibleArchitecture(arch, false, platform_arch_ptr))
return platform_sp;
}
PlatformCreateInstance create_callback;
// First try exact arch matches across all platform plug-ins
uint32_t idx;
for (idx = 0;
(create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx));
++idx) {
PlatformSP platform_sp = create_callback(false, &arch);
if (platform_sp &&
platform_sp->IsCompatibleArchitecture(arch, true, platform_arch_ptr)) {
m_platforms.push_back(platform_sp);
return platform_sp;
}
}
// Next try compatible arch matches across all platform plug-ins
for (idx = 0;
(create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx));
++idx) {
PlatformSP platform_sp = create_callback(false, &arch);
if (platform_sp &&
platform_sp->IsCompatibleArchitecture(arch, false, platform_arch_ptr)) {
m_platforms.push_back(platform_sp);
return platform_sp;
}
}
if (platform_arch_ptr)
platform_arch_ptr->Clear();
return nullptr;
}
PlatformSP PlatformList::GetOrCreate(const ArchSpec &arch,
ArchSpec *platform_arch_ptr) {
Status error;
if (arch.IsValid())
return GetOrCreate(arch, platform_arch_ptr, error);
return nullptr;
}
PlatformSP PlatformList::Create(llvm::StringRef name) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
PlatformSP platform_sp = Platform::Create(name);
m_platforms.push_back(platform_sp);
return platform_sp;
}

View File

@@ -2890,8 +2890,8 @@ void Process::CompleteAttach() {
if (target_arch.IsValid() &&
!platform_sp->IsCompatibleArchitecture(target_arch, false, nullptr)) {
ArchSpec platform_arch;
platform_sp =
platform_sp->GetPlatformForArchitecture(target_arch, &platform_arch);
platform_sp = GetTarget().GetDebugger().GetPlatformList().GetOrCreate(
target_arch, &platform_arch);
if (platform_sp) {
GetTarget().SetPlatform(platform_sp);
GetTarget().SetArchitecture(platform_arch);

View File

@@ -1472,9 +1472,9 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) {
if (!platform_sp ||
!platform_sp->IsCompatibleArchitecture(other, false, nullptr)) {
ArchSpec platform_arch;
auto arch_platform_sp =
Platform::GetPlatformForArchitecture(other, &platform_arch);
if (arch_platform_sp) {
if (PlatformSP arch_platform_sp =
GetDebugger().GetPlatformList().GetOrCreate(other,
&platform_arch)) {
SetPlatform(arch_platform_sp);
if (platform_arch.IsValid())
other = platform_arch;

View File

@@ -79,8 +79,9 @@ Status TargetList::CreateTargetInternal(
const OptionGroupPlatform *platform_options, TargetSP &target_sp) {
Status error;
PlatformList &platform_list = debugger.GetPlatformList();
// Let's start by looking at the selected platform.
PlatformSP platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
PlatformSP platform_sp = platform_list.GetSelectedPlatform();
// This variable corresponds to the architecture specified by the triple
// string. If that string was empty the currently selected platform will
@@ -200,9 +201,8 @@ Status TargetList::CreateTargetInternal(
// Finally find a platform that matches the architecture in the
// executable file.
PlatformSP fallback_platform_sp(
Platform::GetPlatformForArchitecture(
module_spec.GetArchitecture(), nullptr));
PlatformSP fallback_platform_sp = platform_list.GetOrCreate(
module_spec.GetArchitecture(), nullptr);
if (fallback_platform_sp) {
platforms.push_back(fallback_platform_sp);
}
@@ -258,19 +258,19 @@ Status TargetList::CreateTargetInternal(
// compatible with that architecture.
if (!prefer_platform_arch && arch.IsValid()) {
if (!platform_sp->IsCompatibleArchitecture(arch, false, nullptr)) {
platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
platform_sp = platform_list.GetOrCreate(arch, &platform_arch);
if (platform_sp)
debugger.GetPlatformList().SetSelectedPlatform(platform_sp);
platform_list.SetSelectedPlatform(platform_sp);
}
} else if (platform_arch.IsValid()) {
// If "arch" isn't valid, yet "platform_arch" is, it means we have an
// executable file with a single architecture which should be used.
ArchSpec fixed_platform_arch;
if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, nullptr)) {
platform_sp = Platform::GetPlatformForArchitecture(platform_arch,
&fixed_platform_arch);
platform_sp =
platform_list.GetOrCreate(platform_arch, &fixed_platform_arch);
if (platform_sp)
debugger.GetPlatformList().SetSelectedPlatform(platform_sp);
platform_list.SetSelectedPlatform(platform_sp);
}
}
@@ -299,7 +299,8 @@ Status TargetList::CreateTargetInternal(Debugger &debugger,
if (arch.IsValid()) {
if (!platform_sp ||
!platform_sp->IsCompatibleArchitecture(arch, false, nullptr))
platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
platform_sp =
debugger.GetPlatformList().GetOrCreate(specified_arch, &arch);
}
if (!platform_sp)

View File

@@ -92,3 +92,55 @@ class DebuggerAPITestCase(TestBase):
# Test the local property again, is it set to new_cache_line_size?
self.assertEqual(get_cache_line_size(), new_cache_line_size)
def test_CreateTarget_platform(self):
exe = self.getBuildArtifact("a.out")
self.yaml2obj("elf.yaml", exe)
error = lldb.SBError()
target1 = self.dbg.CreateTarget(exe, None, "remote-linux",
False, error)
self.assertSuccess(error)
platform1 = target1.GetPlatform()
platform1.SetWorkingDirectory("/foo/bar")
# Reuse a platform if it matches the currently selected one...
target2 = self.dbg.CreateTarget(exe, None, "remote-linux",
False, error)
self.assertSuccess(error)
platform2 = target2.GetPlatform()
self.assertEqual(platform2.GetWorkingDirectory(), "/foo/bar")
# ... but create a new one if it doesn't.
self.dbg.SetSelectedPlatform(lldb.SBPlatform("remote-windows"))
target3 = self.dbg.CreateTarget(exe, None, "remote-linux",
False, error)
self.assertSuccess(error)
platform3 = target3.GetPlatform()
self.assertIsNone(platform3.GetWorkingDirectory())
def test_CreateTarget_arch(self):
exe = self.getBuildArtifact("a.out")
if lldbplatformutil.getHostPlatform() == 'linux':
self.yaml2obj("macho.yaml", exe)
arch = "x86_64-apple-macosx"
else:
self.yaml2obj("elf.yaml", exe)
arch = "x86_64-pc-linux"
fbsd = lldb.SBPlatform("remote-freebsd")
self.dbg.SetSelectedPlatform(fbsd)
error = lldb.SBError()
target1 = self.dbg.CreateTarget(exe, arch, None, False, error)
self.assertSuccess(error)
platform1 = target1.GetPlatform()
self.assertEqual(platform1.GetName(), "remote-macosx")
platform1.SetWorkingDirectory("/foo/bar")
# Reuse a platform even if it is not currently selected.
self.dbg.SetSelectedPlatform(fbsd)
target2 = self.dbg.CreateTarget(exe, arch, None, False, error)
self.assertSuccess(error)
platform2 = target2.GetPlatform()
self.assertEqual(platform2.GetName(), "remote-macosx")
self.assertEqual(platform2.GetWorkingDirectory(), "/foo/bar")

View File

@@ -0,0 +1,35 @@
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_X86_64
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
Address: 0x1000
AddressAlign: 0x4
Content: "c3c3c3c3"
- Name: .data
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
Address: 0x2000
AddressAlign: 0x4
Content: "3232"
ProgramHeaders:
- Type: PT_LOAD
Flags: [ PF_X, PF_R ]
VAddr: 0x1000
PAddr: 0x1000
Align: 0x4
FirstSec: .text
LastSec: .text
- Type: PT_LOAD
Flags: [ PF_R, PF_W ]
VAddr: 0x2000
PAddr: 0x1004
Align: 0x4
FirstSec: .data
LastSec: .data

View File

@@ -0,0 +1,42 @@
--- !mach-o
FileHeader:
magic: 0xFEEDFACF
cputype: 0x01000007
cpusubtype: 0x00000003
filetype: 0x00000001
ncmds: 4
sizeofcmds: 1160
flags: 0x00002000
reserved: 0x00000000
LoadCommands:
- cmd: LC_SEGMENT_64
cmdsize: 1032
segname: ''
vmaddr: 0
vmsize: 744
fileoff: 1192
filesize: 744
maxprot: 7
initprot: 7
nsects: 12
flags: 0
Sections:
- sectname: __text
segname: __TEXT
addr: 0x0000000000000000
size: 22
offset: 0x000004A8
align: 4
reloff: 0x00000000
nreloc: 0
flags: 0x80000400
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- cmd: LC_BUILD_VERSION
cmdsize: 24
platform: 1
minos: 658944
sdk: 658944
ntools: 0
...

View File

@@ -25,6 +25,29 @@ class SBPlatformAPICase(TestBase):
plat = lldb.SBPlatform("remote-linux") # arbitrary choice
self.assertTrue(plat)
plat.SetSDKRoot(self.getBuildDir())
self.dbg.SetCurrentPlatform("remote-linux")
self.dbg.SetSelectedPlatform(plat)
self.expect("platform status",
substrs=["Sysroot:", self.getBuildDir()])
def test_SetCurrentPlatform_floating(self):
# floating platforms cannot be referenced by name until they are
# associated with a debugger
floating_platform = lldb.SBPlatform("remote-netbsd")
floating_platform.SetWorkingDirectory(self.getBuildDir())
self.assertSuccess(self.dbg.SetCurrentPlatform("remote-netbsd"))
dbg_platform = self.dbg.GetSelectedPlatform()
self.assertEqual(dbg_platform.GetName(), "remote-netbsd")
self.assertIsNone(dbg_platform.GetWorkingDirectory())
def test_SetCurrentPlatform_associated(self):
# associated platforms are found by name-based lookup
floating_platform = lldb.SBPlatform("remote-netbsd")
floating_platform.SetWorkingDirectory(self.getBuildDir())
orig_platform = self.dbg.GetSelectedPlatform()
self.dbg.SetSelectedPlatform(floating_platform)
self.dbg.SetSelectedPlatform(orig_platform)
self.assertSuccess(self.dbg.SetCurrentPlatform("remote-netbsd"))
dbg_platform = self.dbg.GetSelectedPlatform()
self.assertEqual(dbg_platform.GetName(), "remote-netbsd")
self.assertEqual(dbg_platform.GetWorkingDirectory(), self.getBuildDir())