739 lines · cpp
1//===-- SBPlatform.cpp ----------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/API/SBPlatform.h"10#include "lldb/API/SBDebugger.h"11#include "lldb/API/SBEnvironment.h"12#include "lldb/API/SBError.h"13#include "lldb/API/SBFileSpec.h"14#include "lldb/API/SBLaunchInfo.h"15#include "lldb/API/SBModuleSpec.h"16#include "lldb/API/SBProcessInfoList.h"17#include "lldb/API/SBTarget.h"18#include "lldb/API/SBUnixSignals.h"19#include "lldb/Host/File.h"20#include "lldb/Target/Platform.h"21#include "lldb/Target/Target.h"22#include "lldb/Utility/ArchSpec.h"23#include "lldb/Utility/Args.h"24#include "lldb/Utility/Instrumentation.h"25#include "lldb/Utility/Status.h"26 27#include "llvm/Support/FileSystem.h"28 29#include <functional>30 31using namespace lldb;32using namespace lldb_private;33 34// PlatformConnectOptions35struct PlatformConnectOptions {36 PlatformConnectOptions(const char *url = nullptr) {37 if (url && url[0])38 m_url = url;39 }40 41 ~PlatformConnectOptions() = default;42 43 std::string m_url;44 std::string m_rsync_options;45 std::string m_rsync_remote_path_prefix;46 bool m_rsync_enabled = false;47 bool m_rsync_omit_hostname_from_remote_path = false;48 ConstString m_local_cache_directory;49};50 51// PlatformShellCommand52struct PlatformShellCommand {53 PlatformShellCommand(llvm::StringRef shell_interpreter,54 llvm::StringRef shell_command) {55 if (!shell_interpreter.empty())56 m_shell = shell_interpreter.str();57 58 if (!m_shell.empty() && !shell_command.empty())59 m_command = shell_command.str();60 }61 62 PlatformShellCommand(llvm::StringRef shell_command = llvm::StringRef()) {63 if (!shell_command.empty())64 m_command = shell_command.str();65 }66 67 ~PlatformShellCommand() = default;68 69 std::string m_shell;70 std::string m_command;71 std::string m_working_dir;72 std::string m_output;73 int m_status = 0;74 int m_signo = 0;75 Timeout<std::ratio<1>> m_timeout = std::nullopt;76};77// SBPlatformConnectOptions78SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url)79 : m_opaque_ptr(new PlatformConnectOptions(url)) {80 LLDB_INSTRUMENT_VA(this, url);81}82 83SBPlatformConnectOptions::SBPlatformConnectOptions(84 const SBPlatformConnectOptions &rhs)85 : m_opaque_ptr(new PlatformConnectOptions()) {86 LLDB_INSTRUMENT_VA(this, rhs);87 88 *m_opaque_ptr = *rhs.m_opaque_ptr;89}90 91SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; }92 93SBPlatformConnectOptions &94SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) {95 LLDB_INSTRUMENT_VA(this, rhs);96 97 *m_opaque_ptr = *rhs.m_opaque_ptr;98 return *this;99}100 101const char *SBPlatformConnectOptions::GetURL() {102 LLDB_INSTRUMENT_VA(this);103 104 if (m_opaque_ptr->m_url.empty())105 return nullptr;106 return ConstString(m_opaque_ptr->m_url.c_str()).GetCString();107}108 109void SBPlatformConnectOptions::SetURL(const char *url) {110 LLDB_INSTRUMENT_VA(this, url);111 112 if (url && url[0])113 m_opaque_ptr->m_url = url;114 else115 m_opaque_ptr->m_url.clear();116}117 118bool SBPlatformConnectOptions::GetRsyncEnabled() {119 LLDB_INSTRUMENT_VA(this);120 121 return m_opaque_ptr->m_rsync_enabled;122}123 124void SBPlatformConnectOptions::EnableRsync(125 const char *options, const char *remote_path_prefix,126 bool omit_hostname_from_remote_path) {127 LLDB_INSTRUMENT_VA(this, options, remote_path_prefix,128 omit_hostname_from_remote_path);129 130 m_opaque_ptr->m_rsync_enabled = true;131 m_opaque_ptr->m_rsync_omit_hostname_from_remote_path =132 omit_hostname_from_remote_path;133 if (remote_path_prefix && remote_path_prefix[0])134 m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix;135 else136 m_opaque_ptr->m_rsync_remote_path_prefix.clear();137 138 if (options && options[0])139 m_opaque_ptr->m_rsync_options = options;140 else141 m_opaque_ptr->m_rsync_options.clear();142}143 144void SBPlatformConnectOptions::DisableRsync() {145 LLDB_INSTRUMENT_VA(this);146 147 m_opaque_ptr->m_rsync_enabled = false;148}149 150const char *SBPlatformConnectOptions::GetLocalCacheDirectory() {151 LLDB_INSTRUMENT_VA(this);152 153 return m_opaque_ptr->m_local_cache_directory.GetCString();154}155 156void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) {157 LLDB_INSTRUMENT_VA(this, path);158 159 if (path && path[0])160 m_opaque_ptr->m_local_cache_directory.SetCString(path);161 else162 m_opaque_ptr->m_local_cache_directory = ConstString();163}164 165// SBPlatformShellCommand166SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_interpreter,167 const char *shell_command)168 : m_opaque_ptr(new PlatformShellCommand(shell_interpreter, shell_command)) {169 LLDB_INSTRUMENT_VA(this, shell_interpreter, shell_command);170}171 172SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command)173 : m_opaque_ptr(new PlatformShellCommand(shell_command)) {174 LLDB_INSTRUMENT_VA(this, shell_command);175}176 177SBPlatformShellCommand::SBPlatformShellCommand(178 const SBPlatformShellCommand &rhs)179 : m_opaque_ptr(new PlatformShellCommand()) {180 LLDB_INSTRUMENT_VA(this, rhs);181 182 *m_opaque_ptr = *rhs.m_opaque_ptr;183}184 185SBPlatformShellCommand &186SBPlatformShellCommand::operator=(const SBPlatformShellCommand &rhs) {187 188 LLDB_INSTRUMENT_VA(this, rhs);189 190 *m_opaque_ptr = *rhs.m_opaque_ptr;191 return *this;192}193 194SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; }195 196void SBPlatformShellCommand::Clear() {197 LLDB_INSTRUMENT_VA(this);198 199 m_opaque_ptr->m_output = std::string();200 m_opaque_ptr->m_status = 0;201 m_opaque_ptr->m_signo = 0;202}203 204const char *SBPlatformShellCommand::GetShell() {205 LLDB_INSTRUMENT_VA(this);206 207 if (m_opaque_ptr->m_shell.empty())208 return nullptr;209 return ConstString(m_opaque_ptr->m_shell.c_str()).GetCString();210}211 212void SBPlatformShellCommand::SetShell(const char *shell_interpreter) {213 LLDB_INSTRUMENT_VA(this, shell_interpreter);214 215 if (shell_interpreter && shell_interpreter[0])216 m_opaque_ptr->m_shell = shell_interpreter;217 else218 m_opaque_ptr->m_shell.clear();219}220 221const char *SBPlatformShellCommand::GetCommand() {222 LLDB_INSTRUMENT_VA(this);223 224 if (m_opaque_ptr->m_command.empty())225 return nullptr;226 return ConstString(m_opaque_ptr->m_command.c_str()).GetCString();227}228 229void SBPlatformShellCommand::SetCommand(const char *shell_command) {230 LLDB_INSTRUMENT_VA(this, shell_command);231 232 if (shell_command && shell_command[0])233 m_opaque_ptr->m_command = shell_command;234 else235 m_opaque_ptr->m_command.clear();236}237 238const char *SBPlatformShellCommand::GetWorkingDirectory() {239 LLDB_INSTRUMENT_VA(this);240 241 if (m_opaque_ptr->m_working_dir.empty())242 return nullptr;243 return ConstString(m_opaque_ptr->m_working_dir.c_str()).GetCString();244}245 246void SBPlatformShellCommand::SetWorkingDirectory(const char *path) {247 LLDB_INSTRUMENT_VA(this, path);248 249 if (path && path[0])250 m_opaque_ptr->m_working_dir = path;251 else252 m_opaque_ptr->m_working_dir.clear();253}254 255uint32_t SBPlatformShellCommand::GetTimeoutSeconds() {256 LLDB_INSTRUMENT_VA(this);257 258 if (m_opaque_ptr->m_timeout)259 return m_opaque_ptr->m_timeout->count();260 return UINT32_MAX;261}262 263void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) {264 LLDB_INSTRUMENT_VA(this, sec);265 266 if (sec == UINT32_MAX)267 m_opaque_ptr->m_timeout = std::nullopt;268 else269 m_opaque_ptr->m_timeout = std::chrono::seconds(sec);270}271 272int SBPlatformShellCommand::GetSignal() {273 LLDB_INSTRUMENT_VA(this);274 275 return m_opaque_ptr->m_signo;276}277 278int SBPlatformShellCommand::GetStatus() {279 LLDB_INSTRUMENT_VA(this);280 281 return m_opaque_ptr->m_status;282}283 284const char *SBPlatformShellCommand::GetOutput() {285 LLDB_INSTRUMENT_VA(this);286 287 if (m_opaque_ptr->m_output.empty())288 return nullptr;289 return ConstString(m_opaque_ptr->m_output.c_str()).GetCString();290}291 292// SBPlatform293SBPlatform::SBPlatform() { LLDB_INSTRUMENT_VA(this); }294 295SBPlatform::SBPlatform(const char *platform_name) {296 LLDB_INSTRUMENT_VA(this, platform_name);297 298 m_opaque_sp = Platform::Create(platform_name);299}300 301SBPlatform::SBPlatform(const SBPlatform &rhs) {302 LLDB_INSTRUMENT_VA(this, rhs);303 304 m_opaque_sp = rhs.m_opaque_sp;305}306 307SBPlatform &SBPlatform::operator=(const SBPlatform &rhs) {308 LLDB_INSTRUMENT_VA(this, rhs);309 310 m_opaque_sp = rhs.m_opaque_sp;311 return *this;312}313 314SBPlatform::~SBPlatform() = default;315 316SBPlatform SBPlatform::GetHostPlatform() {317 LLDB_INSTRUMENT();318 319 SBPlatform host_platform;320 host_platform.m_opaque_sp = Platform::GetHostPlatform();321 return host_platform;322}323 324bool SBPlatform::IsValid() const {325 LLDB_INSTRUMENT_VA(this);326 return this->operator bool();327}328SBPlatform::operator bool() const {329 LLDB_INSTRUMENT_VA(this);330 331 return m_opaque_sp.get() != nullptr;332}333 334bool SBPlatform::IsHost() const {335 LLDB_INSTRUMENT_VA(this);336 return m_opaque_sp.get() != nullptr && m_opaque_sp->IsHost();337}338 339void SBPlatform::Clear() {340 LLDB_INSTRUMENT_VA(this);341 342 m_opaque_sp.reset();343}344 345const char *SBPlatform::GetName() {346 LLDB_INSTRUMENT_VA(this);347 348 PlatformSP platform_sp(GetSP());349 if (platform_sp)350 return ConstString(platform_sp->GetName()).AsCString();351 return nullptr;352}353 354lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; }355 356void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) {357 m_opaque_sp = platform_sp;358}359 360const char *SBPlatform::GetWorkingDirectory() {361 LLDB_INSTRUMENT_VA(this);362 363 PlatformSP platform_sp(GetSP());364 if (platform_sp)365 return platform_sp->GetWorkingDirectory().GetPathAsConstString().AsCString();366 return nullptr;367}368 369bool SBPlatform::SetWorkingDirectory(const char *path) {370 LLDB_INSTRUMENT_VA(this, path);371 372 PlatformSP platform_sp(GetSP());373 if (platform_sp) {374 if (path)375 platform_sp->SetWorkingDirectory(FileSpec(path));376 else377 platform_sp->SetWorkingDirectory(FileSpec());378 return true;379 }380 return false;381}382 383SBError SBPlatform::ConnectRemote(SBPlatformConnectOptions &connect_options) {384 LLDB_INSTRUMENT_VA(this, connect_options);385 386 SBError sb_error;387 PlatformSP platform_sp(GetSP());388 if (platform_sp && connect_options.GetURL()) {389 Args args;390 args.AppendArgument(connect_options.GetURL());391 sb_error.ref() = platform_sp->ConnectRemote(args);392 } else {393 sb_error = Status::FromErrorString("invalid platform");394 }395 return sb_error;396}397 398void SBPlatform::DisconnectRemote() {399 LLDB_INSTRUMENT_VA(this);400 401 PlatformSP platform_sp(GetSP());402 if (platform_sp)403 platform_sp->DisconnectRemote();404}405 406bool SBPlatform::IsConnected() {407 LLDB_INSTRUMENT_VA(this);408 409 PlatformSP platform_sp(GetSP());410 if (platform_sp)411 return platform_sp->IsConnected();412 return false;413}414 415const char *SBPlatform::GetTriple() {416 LLDB_INSTRUMENT_VA(this);417 418 PlatformSP platform_sp(GetSP());419 if (platform_sp) {420 ArchSpec arch(platform_sp->GetSystemArchitecture());421 if (arch.IsValid()) {422 // Const-ify the string so we don't need to worry about the lifetime of423 // the string424 return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();425 }426 }427 return nullptr;428}429 430const char *SBPlatform::GetOSBuild() {431 LLDB_INSTRUMENT_VA(this);432 433 PlatformSP platform_sp(GetSP());434 if (platform_sp) {435 std::string s = platform_sp->GetOSBuildString().value_or("");436 if (!s.empty()) {437 // Const-ify the string so we don't need to worry about the lifetime of438 // the string439 return ConstString(s).GetCString();440 }441 }442 return nullptr;443}444 445const char *SBPlatform::GetOSDescription() {446 LLDB_INSTRUMENT_VA(this);447 448 PlatformSP platform_sp(GetSP());449 if (platform_sp) {450 std::string s = platform_sp->GetOSKernelDescription().value_or("");451 if (!s.empty()) {452 // Const-ify the string so we don't need to worry about the lifetime of453 // the string454 return ConstString(s.c_str()).GetCString();455 }456 }457 return nullptr;458}459 460const char *SBPlatform::GetHostname() {461 LLDB_INSTRUMENT_VA(this);462 463 PlatformSP platform_sp(GetSP());464 if (platform_sp)465 return ConstString(platform_sp->GetHostname()).GetCString();466 return nullptr;467}468 469uint32_t SBPlatform::GetOSMajorVersion() {470 LLDB_INSTRUMENT_VA(this);471 472 llvm::VersionTuple version;473 if (PlatformSP platform_sp = GetSP())474 version = platform_sp->GetOSVersion();475 return version.empty() ? UINT32_MAX : version.getMajor();476}477 478uint32_t SBPlatform::GetOSMinorVersion() {479 LLDB_INSTRUMENT_VA(this);480 481 llvm::VersionTuple version;482 if (PlatformSP platform_sp = GetSP())483 version = platform_sp->GetOSVersion();484 return version.getMinor().value_or(UINT32_MAX);485}486 487uint32_t SBPlatform::GetOSUpdateVersion() {488 LLDB_INSTRUMENT_VA(this);489 490 llvm::VersionTuple version;491 if (PlatformSP platform_sp = GetSP())492 version = platform_sp->GetOSVersion();493 return version.getSubminor().value_or(UINT32_MAX);494}495 496void SBPlatform::SetSDKRoot(const char *sysroot) {497 LLDB_INSTRUMENT_VA(this, sysroot);498 if (PlatformSP platform_sp = GetSP())499 platform_sp->SetSDKRootDirectory(llvm::StringRef(sysroot).str());500}501 502SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) {503 LLDB_INSTRUMENT_VA(this, src, dst);504 505 SBError sb_error;506 PlatformSP platform_sp(GetSP());507 if (platform_sp) {508 sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref());509 } else {510 sb_error = Status::FromErrorString("invalid platform");511 }512 return sb_error;513}514 515SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) {516 LLDB_INSTRUMENT_VA(this, src, dst);517 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {518 if (src.Exists()) {519 uint32_t permissions = FileSystem::Instance().GetPermissions(src.ref());520 if (permissions == 0) {521 if (FileSystem::Instance().IsDirectory(src.ref()))522 permissions = eFilePermissionsDirectoryDefault;523 else524 permissions = eFilePermissionsFileDefault;525 }526 527 return platform_sp->PutFile(src.ref(), dst.ref(), permissions);528 }529 530 return Status::FromErrorStringWithFormat(531 "'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());532 });533}534 535SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) {536 LLDB_INSTRUMENT_VA(this, src, dst);537 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {538 if (src.Exists())539 return platform_sp->Install(src.ref(), dst.ref());540 541 Status error;542 error = Status::FromErrorStringWithFormat(543 "'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());544 return error;545 });546}547 548SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) {549 LLDB_INSTRUMENT_VA(this, shell_command);550 return ExecuteConnected(551 [&](const lldb::PlatformSP &platform_sp) {552 const char *command = shell_command.GetCommand();553 if (!command)554 return Status::FromErrorString("invalid shell command (empty)");555 556 if (shell_command.GetWorkingDirectory() == nullptr) {557 std::string platform_working_dir =558 platform_sp->GetWorkingDirectory().GetPath();559 if (!platform_working_dir.empty())560 shell_command.SetWorkingDirectory(platform_working_dir.c_str());561 }562 return platform_sp->RunShellCommand(563 shell_command.m_opaque_ptr->m_shell, command,564 FileSpec(shell_command.GetWorkingDirectory()),565 &shell_command.m_opaque_ptr->m_status,566 &shell_command.m_opaque_ptr->m_signo,567 &shell_command.m_opaque_ptr->m_output,568 shell_command.m_opaque_ptr->m_timeout);569 });570}571 572SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {573 LLDB_INSTRUMENT_VA(this, launch_info);574 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {575 ProcessLaunchInfo info = launch_info.ref();576 Status error = platform_sp->LaunchProcess(info);577 launch_info.set_ref(info);578 return error;579 });580}581 582SBProcess SBPlatform::Attach(SBAttachInfo &attach_info,583 const SBDebugger &debugger, SBTarget &target,584 SBError &error) {585 LLDB_INSTRUMENT_VA(this, attach_info, debugger, target, error);586 587 if (PlatformSP platform_sp = GetSP()) {588 if (platform_sp->IsConnected()) {589 ProcessAttachInfo &info = attach_info.ref();590 Status status;591 ProcessSP process_sp = platform_sp->Attach(info, debugger.ref(),592 target.GetSP().get(), status);593 error.SetError(std::move(status));594 return SBProcess(process_sp);595 }596 597 error = Status::FromErrorString("not connected");598 return {};599 }600 601 error = Status::FromErrorString("invalid platform");602 return {};603}604 605SBProcessInfoList SBPlatform::GetAllProcesses(SBError &error) {606 if (PlatformSP platform_sp = GetSP()) {607 if (platform_sp->IsConnected()) {608 ProcessInstanceInfoList list = platform_sp->GetAllProcesses();609 return SBProcessInfoList(list);610 }611 error = Status::FromErrorString("not connected");612 return {};613 }614 615 error = Status::FromErrorString("invalid platform");616 return {};617}618 619SBError SBPlatform::Kill(const lldb::pid_t pid) {620 LLDB_INSTRUMENT_VA(this, pid);621 return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {622 return platform_sp->KillProcess(pid);623 });624}625 626SBError SBPlatform::ExecuteConnected(627 const std::function<Status(const lldb::PlatformSP &)> &func) {628 SBError sb_error;629 const auto platform_sp(GetSP());630 if (platform_sp) {631 if (platform_sp->IsConnected())632 sb_error.ref() = func(platform_sp);633 else634 sb_error = Status::FromErrorString("not connected");635 } else636 sb_error = Status::FromErrorString("invalid platform");637 638 return sb_error;639}640 641SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) {642 LLDB_INSTRUMENT_VA(this, path, file_permissions);643 644 SBError sb_error;645 PlatformSP platform_sp(GetSP());646 if (platform_sp) {647 sb_error.ref() =648 platform_sp->MakeDirectory(FileSpec(path), file_permissions);649 } else {650 sb_error = Status::FromErrorString("invalid platform");651 }652 return sb_error;653}654 655uint32_t SBPlatform::GetFilePermissions(const char *path) {656 LLDB_INSTRUMENT_VA(this, path);657 658 PlatformSP platform_sp(GetSP());659 if (platform_sp) {660 uint32_t file_permissions = 0;661 platform_sp->GetFilePermissions(FileSpec(path), file_permissions);662 return file_permissions;663 }664 return 0;665}666 667SBError SBPlatform::SetFilePermissions(const char *path,668 uint32_t file_permissions) {669 LLDB_INSTRUMENT_VA(this, path, file_permissions);670 671 SBError sb_error;672 PlatformSP platform_sp(GetSP());673 if (platform_sp) {674 sb_error.ref() =675 platform_sp->SetFilePermissions(FileSpec(path), file_permissions);676 } else {677 sb_error = Status::FromErrorString("invalid platform");678 }679 return sb_error;680}681 682SBUnixSignals SBPlatform::GetUnixSignals() const {683 LLDB_INSTRUMENT_VA(this);684 685 if (auto platform_sp = GetSP())686 return SBUnixSignals{platform_sp};687 688 return SBUnixSignals();689}690 691SBEnvironment SBPlatform::GetEnvironment() {692 LLDB_INSTRUMENT_VA(this);693 PlatformSP platform_sp(GetSP());694 695 if (platform_sp) {696 return SBEnvironment(platform_sp->GetEnvironment());697 }698 699 return SBEnvironment();700}701 702SBError SBPlatform::SetLocateModuleCallback(703 lldb::SBPlatformLocateModuleCallback callback, void *callback_baton) {704 LLDB_INSTRUMENT_VA(this, callback, callback_baton);705 PlatformSP platform_sp(GetSP());706 if (!platform_sp)707 return SBError("invalid platform");708 709 if (!callback) {710 // Clear the callback.711 platform_sp->SetLocateModuleCallback(nullptr);712 return SBError();713 }714 715 // Platform.h does not accept lldb::SBPlatformLocateModuleCallback directly716 // because of the SBModuleSpec and SBFileSpec dependencies. Use a lambda to717 // convert ModuleSpec/FileSpec <--> SBModuleSpec/SBFileSpec for the callback718 // arguments.719 platform_sp->SetLocateModuleCallback(720 [callback, callback_baton](const ModuleSpec &module_spec,721 FileSpec &module_file_spec,722 FileSpec &symbol_file_spec) {723 SBModuleSpec module_spec_sb(module_spec);724 SBFileSpec module_file_spec_sb;725 SBFileSpec symbol_file_spec_sb;726 727 SBError error = callback(callback_baton, module_spec_sb,728 module_file_spec_sb, symbol_file_spec_sb);729 730 if (error.Success()) {731 module_file_spec = module_file_spec_sb.ref();732 symbol_file_spec = symbol_file_spec_sb.ref();733 }734 735 return error.ref().Clone();736 });737 return SBError();738}739