5305 lines · cpp
1//===-- Target.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/Target/Target.h"10#include "lldb/Breakpoint/Breakpoint.h"11#include "lldb/Breakpoint/BreakpointIDList.h"12#include "lldb/Breakpoint/BreakpointPrecondition.h"13#include "lldb/Breakpoint/BreakpointResolver.h"14#include "lldb/Breakpoint/BreakpointResolverAddress.h"15#include "lldb/Breakpoint/BreakpointResolverFileLine.h"16#include "lldb/Breakpoint/BreakpointResolverFileRegex.h"17#include "lldb/Breakpoint/BreakpointResolverName.h"18#include "lldb/Breakpoint/BreakpointResolverScripted.h"19#include "lldb/Breakpoint/Watchpoint.h"20#include "lldb/Core/Debugger.h"21#include "lldb/Core/Module.h"22#include "lldb/Core/ModuleSpec.h"23#include "lldb/Core/PluginManager.h"24#include "lldb/Core/SearchFilter.h"25#include "lldb/Core/Section.h"26#include "lldb/Core/SourceManager.h"27#include "lldb/Core/StructuredDataImpl.h"28#include "lldb/Core/Telemetry.h"29#include "lldb/DataFormatters/FormatterSection.h"30#include "lldb/Expression/DiagnosticManager.h"31#include "lldb/Expression/ExpressionVariable.h"32#include "lldb/Expression/REPL.h"33#include "lldb/Expression/UserExpression.h"34#include "lldb/Expression/UtilityFunction.h"35#include "lldb/Host/Host.h"36#include "lldb/Host/PosixApi.h"37#include "lldb/Host/StreamFile.h"38#include "lldb/Interpreter/CommandInterpreter.h"39#include "lldb/Interpreter/CommandReturnObject.h"40#include "lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h"41#include "lldb/Interpreter/Interfaces/ScriptedStopHookInterface.h"42#include "lldb/Interpreter/OptionGroupWatchpoint.h"43#include "lldb/Interpreter/OptionValues.h"44#include "lldb/Interpreter/Property.h"45#include "lldb/Symbol/Function.h"46#include "lldb/Symbol/ObjectFile.h"47#include "lldb/Symbol/Symbol.h"48#include "lldb/Target/ABI.h"49#include "lldb/Target/ExecutionContext.h"50#include "lldb/Target/Language.h"51#include "lldb/Target/LanguageRuntime.h"52#include "lldb/Target/Process.h"53#include "lldb/Target/RegisterTypeBuilder.h"54#include "lldb/Target/SectionLoadList.h"55#include "lldb/Target/StackFrame.h"56#include "lldb/Target/StackFrameRecognizer.h"57#include "lldb/Target/SystemRuntime.h"58#include "lldb/Target/Thread.h"59#include "lldb/Target/ThreadSpec.h"60#include "lldb/Target/UnixSignals.h"61#include "lldb/Utility/Event.h"62#include "lldb/Utility/FileSpec.h"63#include "lldb/Utility/LLDBAssert.h"64#include "lldb/Utility/LLDBLog.h"65#include "lldb/Utility/Log.h"66#include "lldb/Utility/RealpathPrefixes.h"67#include "lldb/Utility/State.h"68#include "lldb/Utility/StreamString.h"69#include "lldb/Utility/Timer.h"70 71#include "llvm/ADT/ScopeExit.h"72#include "llvm/ADT/SetVector.h"73#include "llvm/Support/ThreadPool.h"74 75#include <memory>76#include <mutex>77#include <optional>78#include <sstream>79 80using namespace lldb;81using namespace lldb_private;82 83namespace {84 85struct ExecutableInstaller {86 87 ExecutableInstaller(PlatformSP platform, ModuleSP module)88 : m_platform{platform}, m_module{module},89 m_local_file{m_module->GetFileSpec()},90 m_remote_file{m_module->GetRemoteInstallFileSpec()} {}91 92 void setupRemoteFile() const { m_module->SetPlatformFileSpec(m_remote_file); }93 94 PlatformSP m_platform;95 ModuleSP m_module;96 const FileSpec m_local_file;97 const FileSpec m_remote_file;98};99 100struct MainExecutableInstaller {101 102 MainExecutableInstaller(PlatformSP platform, ModuleSP module, TargetSP target,103 ProcessLaunchInfo &launch_info)104 : m_platform{platform}, m_module{module},105 m_local_file{m_module->GetFileSpec()},106 m_remote_file{107 getRemoteFileSpec(m_platform, target, m_module, m_local_file)},108 m_launch_info{launch_info} {}109 110 void setupRemoteFile() const {111 m_module->SetPlatformFileSpec(m_remote_file);112 m_launch_info.SetExecutableFile(m_remote_file,113 /*add_exe_file_as_first_arg=*/false);114 m_platform->SetFilePermissions(m_remote_file, 0700 /*-rwx------*/);115 }116 117 PlatformSP m_platform;118 ModuleSP m_module;119 const FileSpec m_local_file;120 const FileSpec m_remote_file;121 122private:123 static FileSpec getRemoteFileSpec(PlatformSP platform, TargetSP target,124 ModuleSP module,125 const FileSpec &local_file) {126 FileSpec remote_file = module->GetRemoteInstallFileSpec();127 if (remote_file || !target->GetAutoInstallMainExecutable())128 return remote_file;129 130 if (!local_file)131 return {};132 133 remote_file = platform->GetRemoteWorkingDirectory();134 remote_file.AppendPathComponent(local_file.GetFilename().GetCString());135 136 return remote_file;137 }138 139 ProcessLaunchInfo &m_launch_info;140};141} // namespace142 143static std::atomic<lldb::user_id_t> g_target_unique_id{1};144 145template <typename Installer>146static Status installExecutable(const Installer &installer) {147 if (!installer.m_local_file || !installer.m_remote_file)148 return Status();149 150 Status error = installer.m_platform->Install(installer.m_local_file,151 installer.m_remote_file);152 if (error.Fail())153 return error;154 155 installer.setupRemoteFile();156 return Status();157}158 159Target::Arch::Arch(const ArchSpec &spec)160 : m_spec(spec),161 m_plugin_up(PluginManager::CreateArchitectureInstance(spec)) {}162 163const Target::Arch &Target::Arch::operator=(const ArchSpec &spec) {164 m_spec = spec;165 m_plugin_up = PluginManager::CreateArchitectureInstance(spec);166 return *this;167}168 169llvm::StringRef Target::GetStaticBroadcasterClass() {170 static constexpr llvm::StringLiteral class_name("lldb.target");171 return class_name;172}173 174Target::Target(Debugger &debugger, const ArchSpec &target_arch,175 const lldb::PlatformSP &platform_sp, bool is_dummy_target)176 : TargetProperties(this),177 Broadcaster(debugger.GetBroadcasterManager(),178 Target::GetStaticBroadcasterClass().str()),179 ExecutionContextScope(), m_debugger(debugger), m_platform_sp(platform_sp),180 m_mutex(), m_arch(target_arch), m_images(this), m_section_load_history(),181 m_breakpoint_list(false), m_internal_breakpoint_list(true),182 m_watchpoint_list(), m_process_sp(), m_search_filter_sp(),183 m_image_search_paths(ImageSearchPathsChanged, this),184 m_source_manager_up(), m_stop_hooks(), m_stop_hook_next_id(0),185 m_internal_stop_hooks(), m_latest_stop_hook_id(0), m_valid(true),186 m_suppress_stop_hooks(false), m_is_dummy_target(is_dummy_target),187 m_target_unique_id(g_target_unique_id++),188 m_target_session_name(189 llvm::formatv("Session {0}", m_target_unique_id).str()),190 m_frame_recognizer_manager_up(191 std::make_unique<StackFrameRecognizerManager>()) {192 SetEventName(eBroadcastBitBreakpointChanged, "breakpoint-changed");193 SetEventName(eBroadcastBitModulesLoaded, "modules-loaded");194 SetEventName(eBroadcastBitModulesUnloaded, "modules-unloaded");195 SetEventName(eBroadcastBitWatchpointChanged, "watchpoint-changed");196 SetEventName(eBroadcastBitSymbolsLoaded, "symbols-loaded");197 SetEventName(eBroadcastBitNewTargetCreated, "new-target-created");198 199 CheckInWithManager();200 201 LLDB_LOG(GetLog(LLDBLog::Object), "{0} Target::Target()",202 static_cast<void *>(this));203 if (target_arch.IsValid()) {204 LLDB_LOG(GetLog(LLDBLog::Target),205 "Target::Target created with architecture {0} ({1})",206 target_arch.GetArchitectureName(),207 target_arch.GetTriple().getTriple().c_str());208 }209 210 UpdateLaunchInfoFromProperties();211}212 213Target::~Target() {214 Log *log = GetLog(LLDBLog::Object);215 LLDB_LOG(log, "{0} Target::~Target()", static_cast<void *>(this));216 DeleteCurrentProcess();217}218 219void Target::PrimeFromDummyTarget(Target &target) {220 m_stop_hooks = target.m_stop_hooks;221 m_stop_hook_next_id = target.m_stop_hook_next_id;222 m_internal_stop_hooks = target.m_internal_stop_hooks;223 224 for (const auto &breakpoint_sp : target.m_breakpoint_list.Breakpoints()) {225 if (breakpoint_sp->IsInternal())226 continue;227 228 BreakpointSP new_bp(229 Breakpoint::CopyFromBreakpoint(shared_from_this(), *breakpoint_sp));230 AddBreakpoint(std::move(new_bp), false);231 }232 233 for (const auto &bp_name_entry : target.m_breakpoint_names) {234 AddBreakpointName(std::make_unique<BreakpointName>(*bp_name_entry.second));235 }236 237 m_frame_recognizer_manager_up = std::make_unique<StackFrameRecognizerManager>(238 *target.m_frame_recognizer_manager_up);239 240 m_dummy_signals = target.m_dummy_signals;241}242 243void Target::Dump(Stream *s, lldb::DescriptionLevel description_level) {244 // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);245 if (description_level != lldb::eDescriptionLevelBrief) {246 s->Indent();247 s->PutCString("Target\n");248 s->IndentMore();249 m_images.Dump(s);250 m_breakpoint_list.Dump(s);251 m_internal_breakpoint_list.Dump(s);252 s->IndentLess();253 } else {254 Module *exe_module = GetExecutableModulePointer();255 if (exe_module)256 s->PutCString(exe_module->GetFileSpec().GetFilename().GetCString());257 else258 s->PutCString("No executable module.");259 }260}261 262void Target::CleanupProcess() {263 // Do any cleanup of the target we need to do between process instances.264 // NB It is better to do this before destroying the process in case the265 // clean up needs some help from the process.266 m_breakpoint_list.ClearAllBreakpointSites();267 m_internal_breakpoint_list.ClearAllBreakpointSites();268 ResetBreakpointHitCounts();269 // Disable watchpoints just on the debugger side.270 std::unique_lock<std::recursive_mutex> lock;271 this->GetWatchpointList().GetListMutex(lock);272 DisableAllWatchpoints(false);273 ClearAllWatchpointHitCounts();274 ClearAllWatchpointHistoricValues();275 m_latest_stop_hook_id = 0;276}277 278void Target::DeleteCurrentProcess() {279 if (m_process_sp) {280 // We dispose any active tracing sessions on the current process281 m_trace_sp.reset();282 283 if (m_process_sp->IsAlive())284 m_process_sp->Destroy(false);285 286 m_process_sp->Finalize(false /* not destructing */);287 288 // Let the process finalize itself first, then clear the section load289 // history. Some objects owned by the process might end up calling290 // SectionLoadHistory::SetSectionUnloaded() which can create entries in291 // the section load history that can mess up subsequent processes.292 m_section_load_history.Clear();293 294 CleanupProcess();295 296 m_process_sp.reset();297 }298}299 300const lldb::ProcessSP &Target::CreateProcess(ListenerSP listener_sp,301 llvm::StringRef plugin_name,302 const FileSpec *crash_file,303 bool can_connect) {304 if (!listener_sp)305 listener_sp = GetDebugger().GetListener();306 DeleteCurrentProcess();307 m_process_sp = Process::FindPlugin(shared_from_this(), plugin_name,308 listener_sp, crash_file, can_connect);309 return m_process_sp;310}311 312const lldb::ProcessSP &Target::GetProcessSP() const { return m_process_sp; }313 314lldb::REPLSP Target::GetREPL(Status &err, lldb::LanguageType language,315 const char *repl_options, bool can_create) {316 if (language == eLanguageTypeUnknown)317 language = m_debugger.GetREPLLanguage();318 319 if (language == eLanguageTypeUnknown) {320 LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs();321 322 if (auto single_lang = repl_languages.GetSingularLanguage()) {323 language = *single_lang;324 } else if (repl_languages.Empty()) {325 err = Status::FromErrorString(326 "LLDB isn't configured with REPL support for any languages.");327 return REPLSP();328 } else {329 err = Status::FromErrorString(330 "Multiple possible REPL languages. Please specify a language.");331 return REPLSP();332 }333 }334 335 REPLMap::iterator pos = m_repl_map.find(language);336 337 if (pos != m_repl_map.end()) {338 return pos->second;339 }340 341 if (!can_create) {342 err = Status::FromErrorStringWithFormat(343 "Couldn't find an existing REPL for %s, and can't create a new one",344 Language::GetNameForLanguageType(language));345 return lldb::REPLSP();346 }347 348 Debugger *const debugger = nullptr;349 lldb::REPLSP ret = REPL::Create(err, language, debugger, this, repl_options);350 351 if (ret) {352 m_repl_map[language] = ret;353 return m_repl_map[language];354 }355 356 if (err.Success()) {357 err = Status::FromErrorStringWithFormat(358 "Couldn't create a REPL for %s",359 Language::GetNameForLanguageType(language));360 }361 362 return lldb::REPLSP();363}364 365void Target::SetREPL(lldb::LanguageType language, lldb::REPLSP repl_sp) {366 lldbassert(!m_repl_map.count(language));367 368 m_repl_map[language] = repl_sp;369}370 371void Target::Destroy() {372 std::lock_guard<std::recursive_mutex> guard(m_mutex);373 m_valid = false;374 DeleteCurrentProcess();375 m_platform_sp.reset();376 m_arch = ArchSpec();377 ClearModules(true);378 m_section_load_history.Clear();379 const bool notify = false;380 m_breakpoint_list.RemoveAll(notify);381 m_internal_breakpoint_list.RemoveAll(notify);382 m_last_created_breakpoint.reset();383 m_watchpoint_list.RemoveAll(notify);384 m_last_created_watchpoint.reset();385 m_search_filter_sp.reset();386 m_image_search_paths.Clear(notify);387 m_stop_hooks.clear();388 m_stop_hook_next_id = 0;389 m_internal_stop_hooks.clear();390 m_suppress_stop_hooks = false;391 m_repl_map.clear();392 Args signal_args;393 ClearDummySignals(signal_args);394}395 396llvm::StringRef Target::GetABIName() const {397 lldb::ABISP abi_sp;398 if (m_process_sp)399 abi_sp = m_process_sp->GetABI();400 if (!abi_sp)401 abi_sp = ABI::FindPlugin(ProcessSP(), GetArchitecture());402 if (abi_sp)403 return abi_sp->GetPluginName();404 return {};405}406 407BreakpointList &Target::GetBreakpointList(bool internal) {408 if (internal)409 return m_internal_breakpoint_list;410 else411 return m_breakpoint_list;412}413 414const BreakpointList &Target::GetBreakpointList(bool internal) const {415 if (internal)416 return m_internal_breakpoint_list;417 else418 return m_breakpoint_list;419}420 421BreakpointSP Target::GetBreakpointByID(break_id_t break_id) {422 BreakpointSP bp_sp;423 424 if (LLDB_BREAK_ID_IS_INTERNAL(break_id))425 bp_sp = m_internal_breakpoint_list.FindBreakpointByID(break_id);426 else427 bp_sp = m_breakpoint_list.FindBreakpointByID(break_id);428 429 return bp_sp;430}431 432lldb::BreakpointSP433lldb_private::Target::CreateBreakpointAtUserEntry(Status &error) {434 ModuleSP main_module_sp = GetExecutableModule();435 FileSpecList shared_lib_filter;436 shared_lib_filter.Append(main_module_sp->GetFileSpec());437 llvm::SetVector<std::string, std::vector<std::string>,438 std::unordered_set<std::string>>439 entryPointNamesSet;440 for (LanguageType lang_type : Language::GetSupportedLanguages()) {441 Language *lang = Language::FindPlugin(lang_type);442 if (!lang) {443 error = Status::FromErrorString("Language not found\n");444 return lldb::BreakpointSP();445 }446 std::string entryPointName = lang->GetUserEntryPointName().str();447 if (!entryPointName.empty())448 entryPointNamesSet.insert(entryPointName);449 }450 if (entryPointNamesSet.empty()) {451 error = Status::FromErrorString("No entry point name found\n");452 return lldb::BreakpointSP();453 }454 BreakpointSP bp_sp = CreateBreakpoint(455 &shared_lib_filter,456 /*containingSourceFiles=*/nullptr, entryPointNamesSet.takeVector(),457 /*func_name_type_mask=*/eFunctionNameTypeFull,458 /*language=*/eLanguageTypeUnknown,459 /*offset=*/0,460 /*skip_prologue=*/eLazyBoolNo,461 /*internal=*/false,462 /*hardware=*/false);463 if (!bp_sp) {464 error = Status::FromErrorString("Breakpoint creation failed.\n");465 return lldb::BreakpointSP();466 }467 bp_sp->SetOneShot(true);468 return bp_sp;469}470 471BreakpointSP Target::CreateSourceRegexBreakpoint(472 const FileSpecList *containingModules,473 const FileSpecList *source_file_spec_list,474 const std::unordered_set<std::string> &function_names,475 RegularExpression source_regex, bool internal, bool hardware,476 LazyBool move_to_nearest_code) {477 SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(478 containingModules, source_file_spec_list));479 if (move_to_nearest_code == eLazyBoolCalculate)480 move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;481 BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex(482 nullptr, std::move(source_regex), function_names,483 !static_cast<bool>(move_to_nearest_code)));484 485 return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);486}487 488BreakpointSP Target::CreateBreakpoint(const FileSpecList *containingModules,489 const FileSpec &file, uint32_t line_no,490 uint32_t column, lldb::addr_t offset,491 LazyBool check_inlines,492 LazyBool skip_prologue, bool internal,493 bool hardware,494 LazyBool move_to_nearest_code) {495 FileSpec remapped_file;496 std::optional<llvm::StringRef> removed_prefix_opt =497 GetSourcePathMap().ReverseRemapPath(file, remapped_file);498 if (!removed_prefix_opt)499 remapped_file = file;500 501 if (check_inlines == eLazyBoolCalculate) {502 const InlineStrategy inline_strategy = GetInlineStrategy();503 switch (inline_strategy) {504 case eInlineBreakpointsNever:505 check_inlines = eLazyBoolNo;506 break;507 508 case eInlineBreakpointsHeaders:509 if (remapped_file.IsSourceImplementationFile())510 check_inlines = eLazyBoolNo;511 else512 check_inlines = eLazyBoolYes;513 break;514 515 case eInlineBreakpointsAlways:516 check_inlines = eLazyBoolYes;517 break;518 }519 }520 SearchFilterSP filter_sp;521 if (check_inlines == eLazyBoolNo) {522 // Not checking for inlines, we are looking only for matching compile units523 FileSpecList compile_unit_list;524 compile_unit_list.Append(remapped_file);525 filter_sp = GetSearchFilterForModuleAndCUList(containingModules,526 &compile_unit_list);527 } else {528 filter_sp = GetSearchFilterForModuleList(containingModules);529 }530 if (skip_prologue == eLazyBoolCalculate)531 skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;532 if (move_to_nearest_code == eLazyBoolCalculate)533 move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;534 535 SourceLocationSpec location_spec(remapped_file, line_no, column,536 check_inlines,537 !static_cast<bool>(move_to_nearest_code));538 if (!location_spec)539 return nullptr;540 541 BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine(542 nullptr, offset, skip_prologue, location_spec, removed_prefix_opt));543 return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);544}545 546BreakpointSP Target::CreateBreakpoint(lldb::addr_t addr, bool internal,547 bool hardware) {548 Address so_addr;549 550 // Check for any reason we want to move this breakpoint to other address.551 addr = GetBreakableLoadAddress(addr);552 553 // Attempt to resolve our load address if possible, though it is ok if it554 // doesn't resolve to section/offset.555 556 // Try and resolve as a load address if possible557 GetSectionLoadList().ResolveLoadAddress(addr, so_addr);558 if (!so_addr.IsValid()) {559 // The address didn't resolve, so just set this as an absolute address560 so_addr.SetOffset(addr);561 }562 BreakpointSP bp_sp(CreateBreakpoint(so_addr, internal, hardware));563 return bp_sp;564}565 566BreakpointSP Target::CreateBreakpoint(const Address &addr, bool internal,567 bool hardware) {568 SearchFilterSP filter_sp =569 std::make_shared<SearchFilterForUnconstrainedSearches>(570 shared_from_this());571 BreakpointResolverSP resolver_sp =572 std::make_shared<BreakpointResolverAddress>(nullptr, addr);573 return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, false);574}575 576lldb::BreakpointSP577Target::CreateAddressInModuleBreakpoint(lldb::addr_t file_addr, bool internal,578 const FileSpec &file_spec,579 bool request_hardware) {580 SearchFilterSP filter_sp =581 std::make_shared<SearchFilterForUnconstrainedSearches>(582 shared_from_this());583 BreakpointResolverSP resolver_sp =584 std::make_shared<BreakpointResolverAddress>(nullptr, file_addr,585 file_spec);586 return CreateBreakpoint(filter_sp, resolver_sp, internal, request_hardware,587 false);588}589 590BreakpointSP Target::CreateBreakpoint(591 const FileSpecList *containingModules,592 const FileSpecList *containingSourceFiles, const char *func_name,593 FunctionNameType func_name_type_mask, LanguageType language,594 lldb::addr_t offset, bool offset_is_insn_count, LazyBool skip_prologue,595 bool internal, bool hardware) {596 BreakpointSP bp_sp;597 if (func_name) {598 SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(599 containingModules, containingSourceFiles));600 601 if (skip_prologue == eLazyBoolCalculate)602 skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;603 if (language == lldb::eLanguageTypeUnknown)604 language = GetLanguage().AsLanguageType();605 606 BreakpointResolverSP resolver_sp(new BreakpointResolverName(607 nullptr, func_name, func_name_type_mask, language, Breakpoint::Exact,608 offset, offset_is_insn_count, skip_prologue));609 bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);610 }611 return bp_sp;612}613 614lldb::BreakpointSP615Target::CreateBreakpoint(const FileSpecList *containingModules,616 const FileSpecList *containingSourceFiles,617 const std::vector<std::string> &func_names,618 FunctionNameType func_name_type_mask,619 LanguageType language, lldb::addr_t offset,620 LazyBool skip_prologue, bool internal, bool hardware) {621 BreakpointSP bp_sp;622 size_t num_names = func_names.size();623 if (num_names > 0) {624 SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(625 containingModules, containingSourceFiles));626 627 if (skip_prologue == eLazyBoolCalculate)628 skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;629 if (language == lldb::eLanguageTypeUnknown)630 language = GetLanguage().AsLanguageType();631 632 BreakpointResolverSP resolver_sp(633 new BreakpointResolverName(nullptr, func_names, func_name_type_mask,634 language, offset, skip_prologue));635 bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);636 }637 return bp_sp;638}639 640BreakpointSP641Target::CreateBreakpoint(const FileSpecList *containingModules,642 const FileSpecList *containingSourceFiles,643 const char *func_names[], size_t num_names,644 FunctionNameType func_name_type_mask,645 LanguageType language, lldb::addr_t offset,646 LazyBool skip_prologue, bool internal, bool hardware) {647 BreakpointSP bp_sp;648 if (num_names > 0) {649 SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(650 containingModules, containingSourceFiles));651 652 if (skip_prologue == eLazyBoolCalculate) {653 if (offset == 0)654 skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;655 else656 skip_prologue = eLazyBoolNo;657 }658 if (language == lldb::eLanguageTypeUnknown)659 language = GetLanguage().AsLanguageType();660 661 BreakpointResolverSP resolver_sp(new BreakpointResolverName(662 nullptr, func_names, num_names, func_name_type_mask, language, offset,663 skip_prologue));664 resolver_sp->SetOffset(offset);665 bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);666 }667 return bp_sp;668}669 670SearchFilterSP671Target::GetSearchFilterForModule(const FileSpec *containingModule) {672 SearchFilterSP filter_sp;673 if (containingModule != nullptr) {674 // TODO: We should look into sharing module based search filters675 // across many breakpoints like we do for the simple target based one676 filter_sp = std::make_shared<SearchFilterByModule>(shared_from_this(),677 *containingModule);678 } else {679 if (!m_search_filter_sp)680 m_search_filter_sp =681 std::make_shared<SearchFilterForUnconstrainedSearches>(682 shared_from_this());683 filter_sp = m_search_filter_sp;684 }685 return filter_sp;686}687 688SearchFilterSP689Target::GetSearchFilterForModuleList(const FileSpecList *containingModules) {690 SearchFilterSP filter_sp;691 if (containingModules && containingModules->GetSize() != 0) {692 // TODO: We should look into sharing module based search filters693 // across many breakpoints like we do for the simple target based one694 filter_sp = std::make_shared<SearchFilterByModuleList>(shared_from_this(),695 *containingModules);696 } else {697 if (!m_search_filter_sp)698 m_search_filter_sp =699 std::make_shared<SearchFilterForUnconstrainedSearches>(700 shared_from_this());701 filter_sp = m_search_filter_sp;702 }703 return filter_sp;704}705 706SearchFilterSP Target::GetSearchFilterForModuleAndCUList(707 const FileSpecList *containingModules,708 const FileSpecList *containingSourceFiles) {709 if (containingSourceFiles == nullptr || containingSourceFiles->GetSize() == 0)710 return GetSearchFilterForModuleList(containingModules);711 712 SearchFilterSP filter_sp;713 if (containingModules == nullptr) {714 // We could make a special "CU List only SearchFilter". Better yet was if715 // these could be composable, but that will take a little reworking.716 717 filter_sp = std::make_shared<SearchFilterByModuleListAndCU>(718 shared_from_this(), FileSpecList(), *containingSourceFiles);719 } else {720 filter_sp = std::make_shared<SearchFilterByModuleListAndCU>(721 shared_from_this(), *containingModules, *containingSourceFiles);722 }723 return filter_sp;724}725 726BreakpointSP Target::CreateFuncRegexBreakpoint(727 const FileSpecList *containingModules,728 const FileSpecList *containingSourceFiles, RegularExpression func_regex,729 lldb::LanguageType requested_language, LazyBool skip_prologue,730 bool internal, bool hardware) {731 SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(732 containingModules, containingSourceFiles));733 bool skip = (skip_prologue == eLazyBoolCalculate)734 ? GetSkipPrologue()735 : static_cast<bool>(skip_prologue);736 BreakpointResolverSP resolver_sp(new BreakpointResolverName(737 nullptr, std::move(func_regex), requested_language, 0, skip));738 739 return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);740}741 742lldb::BreakpointSP743Target::CreateExceptionBreakpoint(enum lldb::LanguageType language,744 bool catch_bp, bool throw_bp, bool internal,745 Args *additional_args, Status *error) {746 BreakpointSP exc_bkpt_sp = LanguageRuntime::CreateExceptionBreakpoint(747 *this, language, catch_bp, throw_bp, internal);748 if (exc_bkpt_sp && additional_args) {749 BreakpointPreconditionSP precondition_sp = exc_bkpt_sp->GetPrecondition();750 if (precondition_sp && additional_args) {751 if (error)752 *error = precondition_sp->ConfigurePrecondition(*additional_args);753 else754 precondition_sp->ConfigurePrecondition(*additional_args);755 }756 }757 return exc_bkpt_sp;758}759 760lldb::BreakpointSP Target::CreateScriptedBreakpoint(761 const llvm::StringRef class_name, const FileSpecList *containingModules,762 const FileSpecList *containingSourceFiles, bool internal,763 bool request_hardware, StructuredData::ObjectSP extra_args_sp,764 Status *creation_error) {765 SearchFilterSP filter_sp;766 767 lldb::SearchDepth depth = lldb::eSearchDepthTarget;768 bool has_files =769 containingSourceFiles && containingSourceFiles->GetSize() > 0;770 bool has_modules = containingModules && containingModules->GetSize() > 0;771 772 if (has_files && has_modules) {773 filter_sp = GetSearchFilterForModuleAndCUList(containingModules,774 containingSourceFiles);775 } else if (has_files) {776 filter_sp =777 GetSearchFilterForModuleAndCUList(nullptr, containingSourceFiles);778 } else if (has_modules) {779 filter_sp = GetSearchFilterForModuleList(containingModules);780 } else {781 filter_sp = std::make_shared<SearchFilterForUnconstrainedSearches>(782 shared_from_this());783 }784 785 BreakpointResolverSP resolver_sp(new BreakpointResolverScripted(786 nullptr, class_name, depth, StructuredDataImpl(extra_args_sp)));787 return CreateBreakpoint(filter_sp, resolver_sp, internal, false, true);788}789 790BreakpointSP Target::CreateBreakpoint(SearchFilterSP &filter_sp,791 BreakpointResolverSP &resolver_sp,792 bool internal, bool request_hardware,793 bool resolve_indirect_symbols) {794 BreakpointSP bp_sp;795 if (filter_sp && resolver_sp) {796 const bool hardware = request_hardware || GetRequireHardwareBreakpoints();797 bp_sp.reset(new Breakpoint(*this, filter_sp, resolver_sp, hardware,798 resolve_indirect_symbols));799 resolver_sp->SetBreakpoint(bp_sp);800 AddBreakpoint(bp_sp, internal);801 }802 return bp_sp;803}804 805void Target::AddBreakpoint(lldb::BreakpointSP bp_sp, bool internal) {806 if (!bp_sp)807 return;808 if (internal)809 m_internal_breakpoint_list.Add(bp_sp, false);810 else811 m_breakpoint_list.Add(bp_sp, true);812 813 Log *log = GetLog(LLDBLog::Breakpoints);814 if (log) {815 StreamString s;816 bp_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);817 LLDB_LOGF(log, "Target::%s (internal = %s) => break_id = %s\n",818 __FUNCTION__, bp_sp->IsInternal() ? "yes" : "no", s.GetData());819 }820 821 bp_sp->ResolveBreakpoint();822 823 if (!internal) {824 m_last_created_breakpoint = bp_sp;825 }826}827 828void Target::AddNameToBreakpoint(BreakpointID &id, llvm::StringRef name,829 Status &error) {830 BreakpointSP bp_sp =831 m_breakpoint_list.FindBreakpointByID(id.GetBreakpointID());832 if (!bp_sp) {833 StreamString s;834 id.GetDescription(&s, eDescriptionLevelBrief);835 error = Status::FromErrorStringWithFormat("Could not find breakpoint %s",836 s.GetData());837 return;838 }839 AddNameToBreakpoint(bp_sp, name, error);840}841 842void Target::AddNameToBreakpoint(BreakpointSP &bp_sp, llvm::StringRef name,843 Status &error) {844 if (!bp_sp)845 return;846 847 BreakpointName *bp_name = FindBreakpointName(ConstString(name), true, error);848 if (!bp_name)849 return;850 851 bp_name->ConfigureBreakpoint(bp_sp);852 bp_sp->AddName(name);853}854 855void Target::AddBreakpointName(std::unique_ptr<BreakpointName> bp_name) {856 m_breakpoint_names.insert(857 std::make_pair(bp_name->GetName(), std::move(bp_name)));858}859 860BreakpointName *Target::FindBreakpointName(ConstString name, bool can_create,861 Status &error) {862 BreakpointID::StringIsBreakpointName(name.GetStringRef(), error);863 if (!error.Success())864 return nullptr;865 866 BreakpointNameList::iterator iter = m_breakpoint_names.find(name);867 if (iter != m_breakpoint_names.end()) {868 return iter->second.get();869 }870 871 if (!can_create) {872 error = Status::FromErrorStringWithFormat(873 "Breakpoint name \"%s\" doesn't exist and "874 "can_create is false.",875 name.AsCString());876 return nullptr;877 }878 879 return m_breakpoint_names880 .insert(std::make_pair(name, std::make_unique<BreakpointName>(name)))881 .first->second.get();882}883 884void Target::DeleteBreakpointName(ConstString name) {885 BreakpointNameList::iterator iter = m_breakpoint_names.find(name);886 887 if (iter != m_breakpoint_names.end()) {888 const char *name_cstr = name.AsCString();889 m_breakpoint_names.erase(iter);890 for (auto bp_sp : m_breakpoint_list.Breakpoints())891 bp_sp->RemoveName(name_cstr);892 }893}894 895void Target::RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp,896 ConstString name) {897 bp_sp->RemoveName(name.AsCString());898}899 900void Target::ConfigureBreakpointName(901 BreakpointName &bp_name, const BreakpointOptions &new_options,902 const BreakpointName::Permissions &new_permissions) {903 bp_name.GetOptions().CopyOverSetOptions(new_options);904 bp_name.GetPermissions().MergeInto(new_permissions);905 ApplyNameToBreakpoints(bp_name);906}907 908void Target::ApplyNameToBreakpoints(BreakpointName &bp_name) {909 llvm::Expected<std::vector<BreakpointSP>> expected_vector =910 m_breakpoint_list.FindBreakpointsByName(bp_name.GetName().AsCString());911 912 if (!expected_vector) {913 LLDB_LOG(GetLog(LLDBLog::Breakpoints), "invalid breakpoint name: {}",914 llvm::toString(expected_vector.takeError()));915 return;916 }917 918 for (auto bp_sp : *expected_vector)919 bp_name.ConfigureBreakpoint(bp_sp);920}921 922void Target::GetBreakpointNames(std::vector<std::string> &names) {923 names.clear();924 for (const auto& bp_name_entry : m_breakpoint_names) {925 names.push_back(bp_name_entry.first.AsCString());926 }927 llvm::sort(names);928}929 930bool Target::ProcessIsValid() {931 return (m_process_sp && m_process_sp->IsAlive());932}933 934static bool CheckIfWatchpointsSupported(Target *target, Status &error) {935 std::optional<uint32_t> num_supported_hardware_watchpoints =936 target->GetProcessSP()->GetWatchpointSlotCount();937 938 // If unable to determine the # of watchpoints available,939 // assume they are supported.940 if (!num_supported_hardware_watchpoints)941 return true;942 943 if (*num_supported_hardware_watchpoints == 0) {944 error = Status::FromErrorStringWithFormat(945 "Target supports (%u) hardware watchpoint slots.\n",946 *num_supported_hardware_watchpoints);947 return false;948 }949 return true;950}951 952// See also Watchpoint::SetWatchpointType(uint32_t type) and the953// OptionGroupWatchpoint::WatchType enum type.954WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,955 const CompilerType *type, uint32_t kind,956 Status &error) {957 Log *log = GetLog(LLDBLog::Watchpoints);958 LLDB_LOGF(log,959 "Target::%s (addr = 0x%8.8" PRIx64 " size = %" PRIu64960 " type = %u)\n",961 __FUNCTION__, addr, (uint64_t)size, kind);962 963 WatchpointSP wp_sp;964 if (!ProcessIsValid()) {965 error = Status::FromErrorString("process is not alive");966 return wp_sp;967 }968 969 if (addr == LLDB_INVALID_ADDRESS || size == 0) {970 if (size == 0)971 error = Status::FromErrorString(972 "cannot set a watchpoint with watch_size of 0");973 else974 error = Status::FromErrorStringWithFormat(975 "invalid watch address: %" PRIu64, addr);976 return wp_sp;977 }978 979 if (!LLDB_WATCH_TYPE_IS_VALID(kind)) {980 error =981 Status::FromErrorStringWithFormat("invalid watchpoint type: %d", kind);982 }983 984 if (!CheckIfWatchpointsSupported(this, error))985 return wp_sp;986 987 // Currently we only support one watchpoint per address, with total number of988 // watchpoints limited by the hardware which the inferior is running on.989 990 // Grab the list mutex while doing operations.991 const bool notify = false; // Don't notify about all the state changes we do992 // on creating the watchpoint.993 994 // Mask off ignored bits from watchpoint address.995 if (ABISP abi = m_process_sp->GetABI())996 addr = abi->FixDataAddress(addr);997 998 // LWP_TODO this sequence is looking for an existing watchpoint999 // at the exact same user-specified address, disables the new one1000 // if addr/size/type match. If type/size differ, disable old one.1001 // This isn't correct, we need both watchpoints to use a shared1002 // WatchpointResource in the target, and expand the WatchpointResource1003 // to handle the needs of both Watchpoints.1004 // Also, even if the addresses don't match, they may need to be1005 // supported by the same WatchpointResource, e.g. a watchpoint1006 // watching 1 byte at 0x102 and a watchpoint watching 1 byte at 0x103.1007 // They're in the same word and must be watched by a single hardware1008 // watchpoint register.1009 1010 std::unique_lock<std::recursive_mutex> lock;1011 this->GetWatchpointList().GetListMutex(lock);1012 WatchpointSP matched_sp = m_watchpoint_list.FindByAddress(addr);1013 if (matched_sp) {1014 size_t old_size = matched_sp->GetByteSize();1015 uint32_t old_type =1016 (matched_sp->WatchpointRead() ? LLDB_WATCH_TYPE_READ : 0) |1017 (matched_sp->WatchpointWrite() ? LLDB_WATCH_TYPE_WRITE : 0) |1018 (matched_sp->WatchpointModify() ? LLDB_WATCH_TYPE_MODIFY : 0);1019 // Return the existing watchpoint if both size and type match.1020 if (size == old_size && kind == old_type) {1021 wp_sp = matched_sp;1022 wp_sp->SetEnabled(false, notify);1023 } else {1024 // Nil the matched watchpoint; we will be creating a new one.1025 m_process_sp->DisableWatchpoint(matched_sp, notify);1026 m_watchpoint_list.Remove(matched_sp->GetID(), true);1027 }1028 }1029 1030 if (!wp_sp) {1031 wp_sp = std::make_shared<Watchpoint>(*this, addr, size, type);1032 wp_sp->SetWatchpointType(kind, notify);1033 m_watchpoint_list.Add(wp_sp, true);1034 }1035 1036 error = m_process_sp->EnableWatchpoint(wp_sp, notify);1037 LLDB_LOGF(log, "Target::%s (creation of watchpoint %s with id = %u)\n",1038 __FUNCTION__, error.Success() ? "succeeded" : "failed",1039 wp_sp->GetID());1040 1041 if (error.Fail()) {1042 // Enabling the watchpoint on the device side failed. Remove the said1043 // watchpoint from the list maintained by the target instance.1044 m_watchpoint_list.Remove(wp_sp->GetID(), true);1045 wp_sp.reset();1046 } else1047 m_last_created_watchpoint = wp_sp;1048 return wp_sp;1049}1050 1051void Target::RemoveAllowedBreakpoints() {1052 Log *log = GetLog(LLDBLog::Breakpoints);1053 LLDB_LOGF(log, "Target::%s \n", __FUNCTION__);1054 1055 m_breakpoint_list.RemoveAllowed(true);1056 1057 m_last_created_breakpoint.reset();1058}1059 1060void Target::RemoveAllBreakpoints(bool internal_also) {1061 Log *log = GetLog(LLDBLog::Breakpoints);1062 LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__,1063 internal_also ? "yes" : "no");1064 1065 m_breakpoint_list.RemoveAll(true);1066 if (internal_also)1067 m_internal_breakpoint_list.RemoveAll(false);1068 1069 m_last_created_breakpoint.reset();1070}1071 1072void Target::DisableAllBreakpoints(bool internal_also) {1073 Log *log = GetLog(LLDBLog::Breakpoints);1074 LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__,1075 internal_also ? "yes" : "no");1076 1077 m_breakpoint_list.SetEnabledAll(false);1078 if (internal_also)1079 m_internal_breakpoint_list.SetEnabledAll(false);1080}1081 1082void Target::DisableAllowedBreakpoints() {1083 Log *log = GetLog(LLDBLog::Breakpoints);1084 LLDB_LOGF(log, "Target::%s", __FUNCTION__);1085 1086 m_breakpoint_list.SetEnabledAllowed(false);1087}1088 1089void Target::EnableAllBreakpoints(bool internal_also) {1090 Log *log = GetLog(LLDBLog::Breakpoints);1091 LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__,1092 internal_also ? "yes" : "no");1093 1094 m_breakpoint_list.SetEnabledAll(true);1095 if (internal_also)1096 m_internal_breakpoint_list.SetEnabledAll(true);1097}1098 1099void Target::EnableAllowedBreakpoints() {1100 Log *log = GetLog(LLDBLog::Breakpoints);1101 LLDB_LOGF(log, "Target::%s", __FUNCTION__);1102 1103 m_breakpoint_list.SetEnabledAllowed(true);1104}1105 1106bool Target::RemoveBreakpointByID(break_id_t break_id) {1107 Log *log = GetLog(LLDBLog::Breakpoints);1108 LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,1109 break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");1110 1111 if (DisableBreakpointByID(break_id)) {1112 if (LLDB_BREAK_ID_IS_INTERNAL(break_id))1113 m_internal_breakpoint_list.Remove(break_id, false);1114 else {1115 if (m_last_created_breakpoint) {1116 if (m_last_created_breakpoint->GetID() == break_id)1117 m_last_created_breakpoint.reset();1118 }1119 m_breakpoint_list.Remove(break_id, true);1120 }1121 return true;1122 }1123 return false;1124}1125 1126bool Target::DisableBreakpointByID(break_id_t break_id) {1127 Log *log = GetLog(LLDBLog::Breakpoints);1128 LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,1129 break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");1130 1131 BreakpointSP bp_sp;1132 1133 if (LLDB_BREAK_ID_IS_INTERNAL(break_id))1134 bp_sp = m_internal_breakpoint_list.FindBreakpointByID(break_id);1135 else1136 bp_sp = m_breakpoint_list.FindBreakpointByID(break_id);1137 if (bp_sp) {1138 bp_sp->SetEnabled(false);1139 return true;1140 }1141 return false;1142}1143 1144bool Target::EnableBreakpointByID(break_id_t break_id) {1145 Log *log = GetLog(LLDBLog::Breakpoints);1146 LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,1147 break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");1148 1149 BreakpointSP bp_sp;1150 1151 if (LLDB_BREAK_ID_IS_INTERNAL(break_id))1152 bp_sp = m_internal_breakpoint_list.FindBreakpointByID(break_id);1153 else1154 bp_sp = m_breakpoint_list.FindBreakpointByID(break_id);1155 1156 if (bp_sp) {1157 bp_sp->SetEnabled(true);1158 return true;1159 }1160 return false;1161}1162 1163void Target::ResetBreakpointHitCounts() {1164 GetBreakpointList().ResetHitCounts();1165}1166 1167Status Target::SerializeBreakpointsToFile(const FileSpec &file,1168 const BreakpointIDList &bp_ids,1169 bool append) {1170 Status error;1171 1172 if (!file) {1173 error = Status::FromErrorString("Invalid FileSpec.");1174 return error;1175 }1176 1177 std::string path(file.GetPath());1178 StructuredData::ObjectSP input_data_sp;1179 1180 StructuredData::ArraySP break_store_sp;1181 StructuredData::Array *break_store_ptr = nullptr;1182 1183 if (append) {1184 input_data_sp = StructuredData::ParseJSONFromFile(file, error);1185 if (error.Success()) {1186 break_store_ptr = input_data_sp->GetAsArray();1187 if (!break_store_ptr) {1188 error = Status::FromErrorStringWithFormat(1189 "Tried to append to invalid input file %s", path.c_str());1190 return error;1191 }1192 }1193 }1194 1195 if (!break_store_ptr) {1196 break_store_sp = std::make_shared<StructuredData::Array>();1197 break_store_ptr = break_store_sp.get();1198 }1199 1200 StreamFile out_file(path.c_str(),1201 File::eOpenOptionTruncate | File::eOpenOptionWriteOnly |1202 File::eOpenOptionCanCreate |1203 File::eOpenOptionCloseOnExec,1204 lldb::eFilePermissionsFileDefault);1205 if (!out_file.GetFile().IsValid()) {1206 error = Status::FromErrorStringWithFormat("Unable to open output file: %s.",1207 path.c_str());1208 return error;1209 }1210 1211 std::unique_lock<std::recursive_mutex> lock;1212 GetBreakpointList().GetListMutex(lock);1213 1214 if (bp_ids.GetSize() == 0) {1215 const BreakpointList &breakpoints = GetBreakpointList();1216 1217 size_t num_breakpoints = breakpoints.GetSize();1218 for (size_t i = 0; i < num_breakpoints; i++) {1219 Breakpoint *bp = breakpoints.GetBreakpointAtIndex(i).get();1220 StructuredData::ObjectSP bkpt_save_sp = bp->SerializeToStructuredData();1221 // If a breakpoint can't serialize it, just ignore it for now:1222 if (bkpt_save_sp)1223 break_store_ptr->AddItem(bkpt_save_sp);1224 }1225 } else {1226 1227 std::unordered_set<lldb::break_id_t> processed_bkpts;1228 const size_t count = bp_ids.GetSize();1229 for (size_t i = 0; i < count; ++i) {1230 BreakpointID cur_bp_id = bp_ids.GetBreakpointIDAtIndex(i);1231 lldb::break_id_t bp_id = cur_bp_id.GetBreakpointID();1232 1233 if (bp_id != LLDB_INVALID_BREAK_ID) {1234 // Only do each breakpoint once:1235 std::pair<std::unordered_set<lldb::break_id_t>::iterator, bool>1236 insert_result = processed_bkpts.insert(bp_id);1237 if (!insert_result.second)1238 continue;1239 1240 Breakpoint *bp = GetBreakpointByID(bp_id).get();1241 StructuredData::ObjectSP bkpt_save_sp = bp->SerializeToStructuredData();1242 // If the user explicitly asked to serialize a breakpoint, and we1243 // can't, then raise an error:1244 if (!bkpt_save_sp) {1245 error = Status::FromErrorStringWithFormat(1246 "Unable to serialize breakpoint %d", bp_id);1247 return error;1248 }1249 break_store_ptr->AddItem(bkpt_save_sp);1250 }1251 }1252 }1253 1254 break_store_ptr->Dump(out_file, false);1255 out_file.PutChar('\n');1256 return error;1257}1258 1259Status Target::CreateBreakpointsFromFile(const FileSpec &file,1260 BreakpointIDList &new_bps) {1261 std::vector<std::string> no_names;1262 return CreateBreakpointsFromFile(file, no_names, new_bps);1263}1264 1265Status Target::CreateBreakpointsFromFile(const FileSpec &file,1266 std::vector<std::string> &names,1267 BreakpointIDList &new_bps) {1268 std::unique_lock<std::recursive_mutex> lock;1269 GetBreakpointList().GetListMutex(lock);1270 1271 Status error;1272 StructuredData::ObjectSP input_data_sp =1273 StructuredData::ParseJSONFromFile(file, error);1274 if (!error.Success()) {1275 return error;1276 } else if (!input_data_sp || !input_data_sp->IsValid()) {1277 error = Status::FromErrorStringWithFormat(1278 "Invalid JSON from input file: %s.", file.GetPath().c_str());1279 return error;1280 }1281 1282 StructuredData::Array *bkpt_array = input_data_sp->GetAsArray();1283 if (!bkpt_array) {1284 error = Status::FromErrorStringWithFormat(1285 "Invalid breakpoint data from input file: %s.", file.GetPath().c_str());1286 return error;1287 }1288 1289 size_t num_bkpts = bkpt_array->GetSize();1290 size_t num_names = names.size();1291 1292 for (size_t i = 0; i < num_bkpts; i++) {1293 StructuredData::ObjectSP bkpt_object_sp = bkpt_array->GetItemAtIndex(i);1294 // Peel off the breakpoint key, and feed the rest to the Breakpoint:1295 StructuredData::Dictionary *bkpt_dict = bkpt_object_sp->GetAsDictionary();1296 if (!bkpt_dict) {1297 error = Status::FromErrorStringWithFormat(1298 "Invalid breakpoint data for element %zu from input file: %s.", i,1299 file.GetPath().c_str());1300 return error;1301 }1302 StructuredData::ObjectSP bkpt_data_sp =1303 bkpt_dict->GetValueForKey(Breakpoint::GetSerializationKey());1304 if (num_names &&1305 !Breakpoint::SerializedBreakpointMatchesNames(bkpt_data_sp, names))1306 continue;1307 1308 BreakpointSP bkpt_sp = Breakpoint::CreateFromStructuredData(1309 shared_from_this(), bkpt_data_sp, error);1310 if (!error.Success()) {1311 error = Status::FromErrorStringWithFormat(1312 "Error restoring breakpoint %zu from %s: %s.", i,1313 file.GetPath().c_str(), error.AsCString());1314 return error;1315 }1316 new_bps.AddBreakpointID(BreakpointID(bkpt_sp->GetID()));1317 }1318 return error;1319}1320 1321// The flag 'end_to_end', default to true, signifies that the operation is1322// performed end to end, for both the debugger and the debuggee.1323 1324// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end1325// to end operations.1326bool Target::RemoveAllWatchpoints(bool end_to_end) {1327 Log *log = GetLog(LLDBLog::Watchpoints);1328 LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);1329 1330 if (!end_to_end) {1331 m_watchpoint_list.RemoveAll(true);1332 return true;1333 }1334 1335 // Otherwise, it's an end to end operation.1336 1337 if (!ProcessIsValid())1338 return false;1339 1340 for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {1341 if (!wp_sp)1342 return false;1343 1344 Status rc = m_process_sp->DisableWatchpoint(wp_sp);1345 if (rc.Fail())1346 return false;1347 }1348 m_watchpoint_list.RemoveAll(true);1349 m_last_created_watchpoint.reset();1350 return true; // Success!1351}1352 1353// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end1354// to end operations.1355bool Target::DisableAllWatchpoints(bool end_to_end) {1356 Log *log = GetLog(LLDBLog::Watchpoints);1357 LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);1358 1359 if (!end_to_end) {1360 m_watchpoint_list.SetEnabledAll(false);1361 return true;1362 }1363 1364 // Otherwise, it's an end to end operation.1365 1366 if (!ProcessIsValid())1367 return false;1368 1369 for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {1370 if (!wp_sp)1371 return false;1372 1373 Status rc = m_process_sp->DisableWatchpoint(wp_sp);1374 if (rc.Fail())1375 return false;1376 }1377 return true; // Success!1378}1379 1380// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end1381// to end operations.1382bool Target::EnableAllWatchpoints(bool end_to_end) {1383 Log *log = GetLog(LLDBLog::Watchpoints);1384 LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);1385 1386 if (!end_to_end) {1387 m_watchpoint_list.SetEnabledAll(true);1388 return true;1389 }1390 1391 // Otherwise, it's an end to end operation.1392 1393 if (!ProcessIsValid())1394 return false;1395 1396 for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {1397 if (!wp_sp)1398 return false;1399 1400 Status rc = m_process_sp->EnableWatchpoint(wp_sp);1401 if (rc.Fail())1402 return false;1403 }1404 return true; // Success!1405}1406 1407// Assumption: Caller holds the list mutex lock for m_watchpoint_list.1408bool Target::ClearAllWatchpointHitCounts() {1409 Log *log = GetLog(LLDBLog::Watchpoints);1410 LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);1411 1412 for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {1413 if (!wp_sp)1414 return false;1415 1416 wp_sp->ResetHitCount();1417 }1418 return true; // Success!1419}1420 1421// Assumption: Caller holds the list mutex lock for m_watchpoint_list.1422bool Target::ClearAllWatchpointHistoricValues() {1423 Log *log = GetLog(LLDBLog::Watchpoints);1424 LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);1425 1426 for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {1427 if (!wp_sp)1428 return false;1429 1430 wp_sp->ResetHistoricValues();1431 }1432 return true; // Success!1433}1434 1435// Assumption: Caller holds the list mutex lock for m_watchpoint_list during1436// these operations.1437bool Target::IgnoreAllWatchpoints(uint32_t ignore_count) {1438 Log *log = GetLog(LLDBLog::Watchpoints);1439 LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);1440 1441 if (!ProcessIsValid())1442 return false;1443 1444 for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {1445 if (!wp_sp)1446 return false;1447 1448 wp_sp->SetIgnoreCount(ignore_count);1449 }1450 return true; // Success!1451}1452 1453// Assumption: Caller holds the list mutex lock for m_watchpoint_list.1454bool Target::DisableWatchpointByID(lldb::watch_id_t watch_id) {1455 Log *log = GetLog(LLDBLog::Watchpoints);1456 LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);1457 1458 if (!ProcessIsValid())1459 return false;1460 1461 WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id);1462 if (wp_sp) {1463 Status rc = m_process_sp->DisableWatchpoint(wp_sp);1464 if (rc.Success())1465 return true;1466 1467 // Else, fallthrough.1468 }1469 return false;1470}1471 1472// Assumption: Caller holds the list mutex lock for m_watchpoint_list.1473bool Target::EnableWatchpointByID(lldb::watch_id_t watch_id) {1474 Log *log = GetLog(LLDBLog::Watchpoints);1475 LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);1476 1477 if (!ProcessIsValid())1478 return false;1479 1480 WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id);1481 if (wp_sp) {1482 Status rc = m_process_sp->EnableWatchpoint(wp_sp);1483 if (rc.Success())1484 return true;1485 1486 // Else, fallthrough.1487 }1488 return false;1489}1490 1491// Assumption: Caller holds the list mutex lock for m_watchpoint_list.1492bool Target::RemoveWatchpointByID(lldb::watch_id_t watch_id) {1493 Log *log = GetLog(LLDBLog::Watchpoints);1494 LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);1495 1496 WatchpointSP watch_to_remove_sp = m_watchpoint_list.FindByID(watch_id);1497 if (watch_to_remove_sp == m_last_created_watchpoint)1498 m_last_created_watchpoint.reset();1499 1500 if (DisableWatchpointByID(watch_id)) {1501 m_watchpoint_list.Remove(watch_id, true);1502 return true;1503 }1504 return false;1505}1506 1507// Assumption: Caller holds the list mutex lock for m_watchpoint_list.1508bool Target::IgnoreWatchpointByID(lldb::watch_id_t watch_id,1509 uint32_t ignore_count) {1510 Log *log = GetLog(LLDBLog::Watchpoints);1511 LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);1512 1513 if (!ProcessIsValid())1514 return false;1515 1516 WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id);1517 if (wp_sp) {1518 wp_sp->SetIgnoreCount(ignore_count);1519 return true;1520 }1521 return false;1522}1523 1524ModuleSP Target::GetExecutableModule() {1525 std::lock_guard<std::recursive_mutex> lock(m_images.GetMutex());1526 1527 // Search for the first executable in the module list.1528 for (ModuleSP module_sp : m_images.ModulesNoLocking()) {1529 lldb_private::ObjectFile *obj = module_sp->GetObjectFile();1530 if (obj == nullptr)1531 continue;1532 if (obj->GetType() == ObjectFile::Type::eTypeExecutable)1533 return module_sp;1534 }1535 1536 // If there is none, fall back return the first module loaded.1537 return m_images.GetModuleAtIndex(0);1538}1539 1540Module *Target::GetExecutableModulePointer() {1541 return GetExecutableModule().get();1542}1543 1544static void LoadScriptingResourceForModule(const ModuleSP &module_sp,1545 Target *target) {1546 Status error;1547 StreamString feedback_stream;1548 if (module_sp && !module_sp->LoadScriptingResourceInTarget(target, error,1549 feedback_stream)) {1550 if (error.AsCString())1551 target->GetDebugger().GetAsyncErrorStream()->Printf(1552 "unable to load scripting data for module %s - error reported was "1553 "%s\n",1554 module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),1555 error.AsCString());1556 }1557 if (feedback_stream.GetSize())1558 target->GetDebugger().GetAsyncErrorStream()->Printf(1559 "%s\n", feedback_stream.GetData());1560}1561 1562void Target::ClearModules(bool delete_locations) {1563 ModulesDidUnload(m_images, delete_locations);1564 m_section_load_history.Clear();1565 m_images.Clear();1566 m_scratch_type_system_map.Clear();1567}1568 1569void Target::DidExec() {1570 // When a process exec's we need to know about it so we can do some cleanup.1571 m_breakpoint_list.RemoveInvalidLocations(m_arch.GetSpec());1572 m_internal_breakpoint_list.RemoveInvalidLocations(m_arch.GetSpec());1573}1574 1575void Target::SetExecutableModule(ModuleSP &executable_sp,1576 LoadDependentFiles load_dependent_files) {1577 telemetry::ScopedDispatcher<telemetry::ExecutableModuleInfo> helper(1578 &m_debugger);1579 Log *log = GetLog(LLDBLog::Target);1580 ClearModules(false);1581 1582 if (executable_sp) {1583 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;1584 if (ProcessSP proc = GetProcessSP())1585 pid = proc->GetID();1586 1587 helper.DispatchNow([&](telemetry::ExecutableModuleInfo *info) {1588 info->exec_mod = executable_sp;1589 info->uuid = executable_sp->GetUUID();1590 info->pid = pid;1591 info->triple = executable_sp->GetArchitecture().GetTriple().getTriple();1592 info->is_start_entry = true;1593 });1594 1595 helper.DispatchOnExit([&, pid](telemetry::ExecutableModuleInfo *info) {1596 info->exec_mod = executable_sp;1597 info->uuid = executable_sp->GetUUID();1598 info->pid = pid;1599 });1600 1601 ElapsedTime elapsed(m_stats.GetCreateTime());1602 LLDB_SCOPED_TIMERF("Target::SetExecutableModule (executable = '%s')",1603 executable_sp->GetFileSpec().GetPath().c_str());1604 1605 const bool notify = true;1606 m_images.Append(executable_sp,1607 notify); // The first image is our executable file1608 1609 // If we haven't set an architecture yet, reset our architecture based on1610 // what we found in the executable module.1611 if (!m_arch.GetSpec().IsValid()) {1612 m_arch = executable_sp->GetArchitecture();1613 LLDB_LOG(log,1614 "Target::SetExecutableModule setting architecture to {0} ({1}) "1615 "based on executable file",1616 m_arch.GetSpec().GetArchitectureName(),1617 m_arch.GetSpec().GetTriple().getTriple());1618 }1619 1620 ObjectFile *executable_objfile = executable_sp->GetObjectFile();1621 bool load_dependents = true;1622 switch (load_dependent_files) {1623 case eLoadDependentsDefault:1624 load_dependents = executable_sp->IsExecutable();1625 break;1626 case eLoadDependentsYes:1627 load_dependents = true;1628 break;1629 case eLoadDependentsNo:1630 load_dependents = false;1631 break;1632 }1633 1634 if (executable_objfile && load_dependents) {1635 // FileSpecList is not thread safe and needs to be synchronized.1636 FileSpecList dependent_files;1637 std::mutex dependent_files_mutex;1638 1639 // ModuleList is thread safe.1640 ModuleList added_modules;1641 1642 auto GetDependentModules = [&](FileSpec dependent_file_spec) {1643 FileSpec platform_dependent_file_spec;1644 if (m_platform_sp)1645 m_platform_sp->GetFileWithUUID(dependent_file_spec, nullptr,1646 platform_dependent_file_spec);1647 else1648 platform_dependent_file_spec = dependent_file_spec;1649 1650 ModuleSpec module_spec(platform_dependent_file_spec, m_arch.GetSpec());1651 ModuleSP image_module_sp(1652 GetOrCreateModule(module_spec, false /* notify */));1653 if (image_module_sp) {1654 added_modules.AppendIfNeeded(image_module_sp, false);1655 ObjectFile *objfile = image_module_sp->GetObjectFile();1656 if (objfile) {1657 // Create a local copy of the dependent file list so we don't have1658 // to lock for the whole duration of GetDependentModules.1659 FileSpecList dependent_files_copy;1660 {1661 std::lock_guard<std::mutex> guard(dependent_files_mutex);1662 dependent_files_copy = dependent_files;1663 }1664 1665 // Remember the size of the local copy so we can append only the1666 // modules that have been added by GetDependentModules.1667 const size_t previous_dependent_files =1668 dependent_files_copy.GetSize();1669 1670 objfile->GetDependentModules(dependent_files_copy);1671 1672 {1673 std::lock_guard<std::mutex> guard(dependent_files_mutex);1674 for (size_t i = previous_dependent_files;1675 i < dependent_files_copy.GetSize(); ++i)1676 dependent_files.AppendIfUnique(1677 dependent_files_copy.GetFileSpecAtIndex(i));1678 }1679 }1680 }1681 };1682 1683 executable_objfile->GetDependentModules(dependent_files);1684 1685 llvm::ThreadPoolTaskGroup task_group(Debugger::GetThreadPool());1686 for (uint32_t i = 0; i < dependent_files.GetSize(); i++) {1687 // Process all currently known dependencies in parallel in the innermost1688 // loop. This may create newly discovered dependencies to be appended to1689 // dependent_files. We'll deal with these files during the next1690 // iteration of the outermost loop.1691 {1692 std::lock_guard<std::mutex> guard(dependent_files_mutex);1693 for (; i < dependent_files.GetSize(); i++)1694 task_group.async(GetDependentModules,1695 dependent_files.GetFileSpecAtIndex(i));1696 }1697 task_group.wait();1698 }1699 ModulesDidLoad(added_modules);1700 }1701 }1702}1703 1704bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform,1705 bool merge) {1706 Log *log = GetLog(LLDBLog::Target);1707 bool missing_local_arch = !m_arch.GetSpec().IsValid();1708 bool replace_local_arch = true;1709 bool compatible_local_arch = false;1710 ArchSpec other(arch_spec);1711 1712 // Changing the architecture might mean that the currently selected platform1713 // isn't compatible. Set the platform correctly if we are asked to do so,1714 // otherwise assume the user will set the platform manually.1715 if (set_platform) {1716 if (other.IsValid()) {1717 auto platform_sp = GetPlatform();1718 if (!platform_sp || !platform_sp->IsCompatibleArchitecture(1719 other, {}, ArchSpec::CompatibleMatch, nullptr)) {1720 ArchSpec platform_arch;1721 if (PlatformSP arch_platform_sp =1722 GetDebugger().GetPlatformList().GetOrCreate(other, {},1723 &platform_arch)) {1724 arch_platform_sp->SetLocateModuleCallback(1725 platform_sp->GetLocateModuleCallback());1726 SetPlatform(arch_platform_sp);1727 if (platform_arch.IsValid())1728 other = platform_arch;1729 }1730 }1731 }1732 }1733 1734 if (!missing_local_arch) {1735 if (merge && m_arch.GetSpec().IsCompatibleMatch(arch_spec)) {1736 other.MergeFrom(m_arch.GetSpec());1737 1738 if (m_arch.GetSpec().IsCompatibleMatch(other)) {1739 compatible_local_arch = true;1740 1741 if (m_arch.GetSpec().GetTriple() == other.GetTriple())1742 replace_local_arch = false;1743 }1744 }1745 }1746 1747 if (compatible_local_arch || missing_local_arch) {1748 // If we haven't got a valid arch spec, or the architectures are compatible1749 // update the architecture, unless the one we already have is more1750 // specified1751 if (replace_local_arch)1752 m_arch = other;1753 LLDB_LOG(log,1754 "Target::SetArchitecture merging compatible arch; arch "1755 "is now {0} ({1})",1756 m_arch.GetSpec().GetArchitectureName(),1757 m_arch.GetSpec().GetTriple().getTriple());1758 return true;1759 }1760 1761 // If we have an executable file, try to reset the executable to the desired1762 // architecture1763 LLDB_LOGF(1764 log,1765 "Target::SetArchitecture changing architecture to %s (%s) from %s (%s)",1766 arch_spec.GetArchitectureName(),1767 arch_spec.GetTriple().getTriple().c_str(),1768 m_arch.GetSpec().GetArchitectureName(),1769 m_arch.GetSpec().GetTriple().getTriple().c_str());1770 m_arch = other;1771 ModuleSP executable_sp = GetExecutableModule();1772 1773 ClearModules(true);1774 // Need to do something about unsetting breakpoints.1775 1776 if (executable_sp) {1777 LLDB_LOGF(log,1778 "Target::SetArchitecture Trying to select executable file "1779 "architecture %s (%s)",1780 arch_spec.GetArchitectureName(),1781 arch_spec.GetTriple().getTriple().c_str());1782 ModuleSpec module_spec(executable_sp->GetFileSpec(), other);1783 module_spec.SetTarget(shared_from_this());1784 Status error = ModuleList::GetSharedModule(module_spec, executable_sp,1785 nullptr, nullptr);1786 1787 if (!error.Fail() && executable_sp) {1788 SetExecutableModule(executable_sp, eLoadDependentsYes);1789 return true;1790 }1791 }1792 return false;1793}1794 1795bool Target::MergeArchitecture(const ArchSpec &arch_spec) {1796 Log *log = GetLog(LLDBLog::Target);1797 if (arch_spec.IsValid()) {1798 if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) {1799 // The current target arch is compatible with "arch_spec", see if we can1800 // improve our current architecture using bits from "arch_spec"1801 1802 LLDB_LOGF(log,1803 "Target::MergeArchitecture target has arch %s, merging with "1804 "arch %s",1805 m_arch.GetSpec().GetTriple().getTriple().c_str(),1806 arch_spec.GetTriple().getTriple().c_str());1807 1808 // Merge bits from arch_spec into "merged_arch" and set our architecture1809 ArchSpec merged_arch(m_arch.GetSpec());1810 merged_arch.MergeFrom(arch_spec);1811 return SetArchitecture(merged_arch);1812 } else {1813 // The new architecture is different, we just need to replace it1814 return SetArchitecture(arch_spec);1815 }1816 }1817 return false;1818}1819 1820void Target::NotifyWillClearList(const ModuleList &module_list) {}1821 1822void Target::NotifyModuleAdded(const ModuleList &module_list,1823 const ModuleSP &module_sp) {1824 // A module is being added to this target for the first time1825 if (m_valid) {1826 ModuleList my_module_list;1827 my_module_list.Append(module_sp);1828 ModulesDidLoad(my_module_list);1829 }1830}1831 1832void Target::NotifyModuleRemoved(const ModuleList &module_list,1833 const ModuleSP &module_sp) {1834 // A module is being removed from this target.1835 if (m_valid) {1836 ModuleList my_module_list;1837 my_module_list.Append(module_sp);1838 ModulesDidUnload(my_module_list, false);1839 }1840}1841 1842void Target::NotifyModuleUpdated(const ModuleList &module_list,1843 const ModuleSP &old_module_sp,1844 const ModuleSP &new_module_sp) {1845 // A module is replacing an already added module1846 if (m_valid) {1847 m_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(old_module_sp,1848 new_module_sp);1849 m_internal_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(1850 old_module_sp, new_module_sp);1851 }1852}1853 1854void Target::NotifyModulesRemoved(lldb_private::ModuleList &module_list) {1855 ModulesDidUnload(module_list, false);1856}1857 1858void Target::ModulesDidLoad(ModuleList &module_list) {1859 if (GetPreloadSymbols())1860 module_list.PreloadSymbols(GetParallelModuleLoad());1861 1862 const size_t num_images = module_list.GetSize();1863 if (m_valid && num_images) {1864 for (size_t idx = 0; idx < num_images; ++idx) {1865 ModuleSP module_sp(module_list.GetModuleAtIndex(idx));1866 LoadScriptingResourceForModule(module_sp, this);1867 LoadTypeSummariesForModule(module_sp);1868 LoadFormattersForModule(module_sp);1869 }1870 m_breakpoint_list.UpdateBreakpoints(module_list, true, false);1871 m_internal_breakpoint_list.UpdateBreakpoints(module_list, true, false);1872 if (m_process_sp) {1873 m_process_sp->ModulesDidLoad(module_list);1874 }1875 auto data_sp =1876 std::make_shared<TargetEventData>(shared_from_this(), module_list);1877 BroadcastEvent(eBroadcastBitModulesLoaded, data_sp);1878 }1879}1880 1881void Target::SymbolsDidLoad(ModuleList &module_list) {1882 if (m_valid && module_list.GetSize()) {1883 if (m_process_sp) {1884 for (LanguageRuntime *runtime : m_process_sp->GetLanguageRuntimes()) {1885 runtime->SymbolsDidLoad(module_list);1886 }1887 }1888 1889 m_breakpoint_list.UpdateBreakpoints(module_list, true, false);1890 m_internal_breakpoint_list.UpdateBreakpoints(module_list, true, false);1891 auto data_sp =1892 std::make_shared<TargetEventData>(shared_from_this(), module_list);1893 BroadcastEvent(eBroadcastBitSymbolsLoaded, data_sp);1894 }1895}1896 1897void Target::ModulesDidUnload(ModuleList &module_list, bool delete_locations) {1898 if (m_valid && module_list.GetSize()) {1899 UnloadModuleSections(module_list);1900 auto data_sp =1901 std::make_shared<TargetEventData>(shared_from_this(), module_list);1902 BroadcastEvent(eBroadcastBitModulesUnloaded, data_sp);1903 m_breakpoint_list.UpdateBreakpoints(module_list, false, delete_locations);1904 m_internal_breakpoint_list.UpdateBreakpoints(module_list, false,1905 delete_locations);1906 1907 // If a module was torn down it will have torn down the 'TypeSystemClang's1908 // that we used as source 'ASTContext's for the persistent variables in1909 // the current target. Those would now be unsafe to access because the1910 // 'DeclOrigin' are now possibly stale. Thus clear all persistent1911 // variables. We only want to flush 'TypeSystem's if the module being1912 // unloaded was capable of describing a source type. JITted module unloads1913 // happen frequently for Objective-C utility functions or the REPL and rely1914 // on the persistent variables to stick around.1915 const bool should_flush_type_systems =1916 module_list.AnyOf([](lldb_private::Module &module) {1917 auto *object_file = module.GetObjectFile();1918 1919 if (!object_file)1920 return false;1921 1922 auto type = object_file->GetType();1923 1924 // eTypeExecutable: when debugged binary was rebuilt1925 // eTypeSharedLibrary: if dylib was re-loaded1926 return module.FileHasChanged() &&1927 (type == ObjectFile::eTypeObjectFile ||1928 type == ObjectFile::eTypeExecutable ||1929 type == ObjectFile::eTypeSharedLibrary);1930 });1931 1932 if (should_flush_type_systems)1933 m_scratch_type_system_map.Clear();1934 }1935}1936 1937bool Target::ModuleIsExcludedForUnconstrainedSearches(1938 const FileSpec &module_file_spec) {1939 if (GetBreakpointsConsultPlatformAvoidList()) {1940 ModuleList matchingModules;1941 ModuleSpec module_spec(module_file_spec);1942 GetImages().FindModules(module_spec, matchingModules);1943 size_t num_modules = matchingModules.GetSize();1944 1945 // If there is more than one module for this file spec, only1946 // return true if ALL the modules are on the black list.1947 if (num_modules > 0) {1948 for (size_t i = 0; i < num_modules; i++) {1949 if (!ModuleIsExcludedForUnconstrainedSearches(1950 matchingModules.GetModuleAtIndex(i)))1951 return false;1952 }1953 return true;1954 }1955 }1956 return false;1957}1958 1959bool Target::ModuleIsExcludedForUnconstrainedSearches(1960 const lldb::ModuleSP &module_sp) {1961 if (GetBreakpointsConsultPlatformAvoidList()) {1962 if (m_platform_sp)1963 return m_platform_sp->ModuleIsExcludedForUnconstrainedSearches(*this,1964 module_sp);1965 }1966 return false;1967}1968 1969size_t Target::ReadMemoryFromFileCache(const Address &addr, void *dst,1970 size_t dst_len, Status &error) {1971 SectionSP section_sp(addr.GetSection());1972 if (section_sp) {1973 // If the contents of this section are encrypted, the on-disk file is1974 // unusable. Read only from live memory.1975 if (section_sp->IsEncrypted()) {1976 error = Status::FromErrorString("section is encrypted");1977 return 0;1978 }1979 ModuleSP module_sp(section_sp->GetModule());1980 if (module_sp) {1981 ObjectFile *objfile = section_sp->GetModule()->GetObjectFile();1982 if (objfile) {1983 size_t bytes_read = objfile->ReadSectionData(1984 section_sp.get(), addr.GetOffset(), dst, dst_len);1985 if (bytes_read > 0)1986 return bytes_read;1987 else1988 error = Status::FromErrorStringWithFormat(1989 "error reading data from section %s",1990 section_sp->GetName().GetCString());1991 } else1992 error = Status::FromErrorString("address isn't from a object file");1993 } else1994 error = Status::FromErrorString("address isn't in a module");1995 } else1996 error = Status::FromErrorString(1997 "address doesn't contain a section that points to a "1998 "section in a object file");1999 2000 return 0;2001}2002 2003size_t Target::ReadMemory(const Address &addr, void *dst, size_t dst_len,2004 Status &error, bool force_live_memory,2005 lldb::addr_t *load_addr_ptr,2006 bool *did_read_live_memory) {2007 error.Clear();2008 if (did_read_live_memory)2009 *did_read_live_memory = false;2010 2011 Address fixed_addr = addr;2012 if (ProcessIsValid())2013 if (const ABISP &abi = m_process_sp->GetABI())2014 fixed_addr.SetLoadAddress(abi->FixAnyAddress(addr.GetLoadAddress(this)),2015 this);2016 2017 // if we end up reading this from process memory, we will fill this with the2018 // actual load address2019 if (load_addr_ptr)2020 *load_addr_ptr = LLDB_INVALID_ADDRESS;2021 2022 size_t bytes_read = 0;2023 2024 addr_t load_addr = LLDB_INVALID_ADDRESS;2025 addr_t file_addr = LLDB_INVALID_ADDRESS;2026 Address resolved_addr;2027 if (!fixed_addr.IsSectionOffset()) {2028 SectionLoadList §ion_load_list = GetSectionLoadList();2029 if (section_load_list.IsEmpty()) {2030 // No sections are loaded, so we must assume we are not running yet and2031 // anything we are given is a file address.2032 file_addr =2033 fixed_addr.GetOffset(); // "fixed_addr" doesn't have a section, so2034 // its offset is the file address2035 m_images.ResolveFileAddress(file_addr, resolved_addr);2036 } else {2037 // We have at least one section loaded. This can be because we have2038 // manually loaded some sections with "target modules load ..." or2039 // because we have a live process that has sections loaded through2040 // the dynamic loader2041 load_addr =2042 fixed_addr.GetOffset(); // "fixed_addr" doesn't have a section, so2043 // its offset is the load address2044 section_load_list.ResolveLoadAddress(load_addr, resolved_addr);2045 }2046 }2047 if (!resolved_addr.IsValid())2048 resolved_addr = fixed_addr;2049 2050 // If we read from the file cache but can't get as many bytes as requested,2051 // we keep the result around in this buffer, in case this result is the2052 // best we can do.2053 std::unique_ptr<uint8_t[]> file_cache_read_buffer;2054 size_t file_cache_bytes_read = 0;2055 2056 // Read from file cache if read-only section.2057 if (!force_live_memory && resolved_addr.IsSectionOffset()) {2058 SectionSP section_sp(resolved_addr.GetSection());2059 if (section_sp) {2060 auto permissions = Flags(section_sp->GetPermissions());2061 bool is_readonly = !permissions.Test(ePermissionsWritable) &&2062 permissions.Test(ePermissionsReadable);2063 if (is_readonly) {2064 file_cache_bytes_read =2065 ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);2066 if (file_cache_bytes_read == dst_len)2067 return file_cache_bytes_read;2068 else if (file_cache_bytes_read > 0) {2069 file_cache_read_buffer =2070 std::make_unique<uint8_t[]>(file_cache_bytes_read);2071 std::memcpy(file_cache_read_buffer.get(), dst, file_cache_bytes_read);2072 }2073 }2074 }2075 }2076 2077 if (ProcessIsValid()) {2078 if (load_addr == LLDB_INVALID_ADDRESS)2079 load_addr = resolved_addr.GetLoadAddress(this);2080 2081 if (load_addr == LLDB_INVALID_ADDRESS) {2082 ModuleSP addr_module_sp(resolved_addr.GetModule());2083 if (addr_module_sp && addr_module_sp->GetFileSpec())2084 error = Status::FromErrorStringWithFormatv(2085 "{0:F}[{1:x+}] can't be resolved, {0:F} is not currently loaded",2086 addr_module_sp->GetFileSpec(), resolved_addr.GetFileAddress());2087 else2088 error = Status::FromErrorStringWithFormat(2089 "0x%" PRIx64 " can't be resolved", resolved_addr.GetFileAddress());2090 } else {2091 bytes_read = m_process_sp->ReadMemory(load_addr, dst, dst_len, error);2092 if (bytes_read != dst_len) {2093 if (error.Success()) {2094 if (bytes_read == 0)2095 error = Status::FromErrorStringWithFormat(2096 "read memory from 0x%" PRIx64 " failed", load_addr);2097 else2098 error = Status::FromErrorStringWithFormat(2099 "only %" PRIu64 " of %" PRIu642100 " bytes were read from memory at 0x%" PRIx64,2101 (uint64_t)bytes_read, (uint64_t)dst_len, load_addr);2102 }2103 }2104 if (bytes_read) {2105 if (load_addr_ptr)2106 *load_addr_ptr = load_addr;2107 if (did_read_live_memory)2108 *did_read_live_memory = true;2109 return bytes_read;2110 }2111 }2112 }2113 2114 if (file_cache_read_buffer && file_cache_bytes_read > 0) {2115 // Reading from the process failed. If we've previously succeeded in reading2116 // something from the file cache, then copy that over and return that.2117 std::memcpy(dst, file_cache_read_buffer.get(), file_cache_bytes_read);2118 return file_cache_bytes_read;2119 }2120 2121 if (!file_cache_read_buffer && resolved_addr.IsSectionOffset()) {2122 // If we didn't already try and read from the object file cache, then try2123 // it after failing to read from the process.2124 return ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);2125 }2126 return 0;2127}2128 2129size_t Target::ReadCStringFromMemory(const Address &addr, std::string &out_str,2130 Status &error, bool force_live_memory) {2131 char buf[256];2132 out_str.clear();2133 addr_t curr_addr = addr.GetLoadAddress(this);2134 Address address(addr);2135 while (true) {2136 size_t length = ReadCStringFromMemory(address, buf, sizeof(buf), error,2137 force_live_memory);2138 if (length == 0)2139 break;2140 out_str.append(buf, length);2141 // If we got "length - 1" bytes, we didn't get the whole C string, we need2142 // to read some more characters2143 if (length == sizeof(buf) - 1)2144 curr_addr += length;2145 else2146 break;2147 address = Address(curr_addr);2148 }2149 return out_str.size();2150}2151 2152size_t Target::ReadCStringFromMemory(const Address &addr, char *dst,2153 size_t dst_max_len, Status &result_error,2154 bool force_live_memory) {2155 size_t total_cstr_len = 0;2156 if (dst && dst_max_len) {2157 result_error.Clear();2158 // NULL out everything just to be safe2159 memset(dst, 0, dst_max_len);2160 addr_t curr_addr = addr.GetLoadAddress(this);2161 Address address(addr);2162 2163 // We could call m_process_sp->GetMemoryCacheLineSize() but I don't think2164 // this really needs to be tied to the memory cache subsystem's cache line2165 // size, so leave this as a fixed constant.2166 const size_t cache_line_size = 512;2167 2168 size_t bytes_left = dst_max_len - 1;2169 char *curr_dst = dst;2170 2171 while (bytes_left > 0) {2172 addr_t cache_line_bytes_left =2173 cache_line_size - (curr_addr % cache_line_size);2174 addr_t bytes_to_read =2175 std::min<addr_t>(bytes_left, cache_line_bytes_left);2176 Status error;2177 size_t bytes_read = ReadMemory(address, curr_dst, bytes_to_read, error,2178 force_live_memory);2179 2180 if (bytes_read == 0) {2181 result_error = std::move(error);2182 dst[total_cstr_len] = '\0';2183 break;2184 }2185 const size_t len = strlen(curr_dst);2186 2187 total_cstr_len += len;2188 2189 if (len < bytes_to_read)2190 break;2191 2192 curr_dst += bytes_read;2193 curr_addr += bytes_read;2194 bytes_left -= bytes_read;2195 address = Address(curr_addr);2196 }2197 } else {2198 if (dst == nullptr)2199 result_error = Status::FromErrorString("invalid arguments");2200 else2201 result_error.Clear();2202 }2203 return total_cstr_len;2204}2205 2206addr_t Target::GetReasonableReadSize(const Address &addr) {2207 addr_t load_addr = addr.GetLoadAddress(this);2208 if (load_addr != LLDB_INVALID_ADDRESS && m_process_sp) {2209 // Avoid crossing cache line boundaries.2210 addr_t cache_line_size = m_process_sp->GetMemoryCacheLineSize();2211 return cache_line_size - (load_addr % cache_line_size);2212 }2213 2214 // The read is going to go to the file cache, so we can just pick a largish2215 // value.2216 return 0x1000;2217}2218 2219size_t Target::ReadStringFromMemory(const Address &addr, char *dst,2220 size_t max_bytes, Status &error,2221 size_t type_width, bool force_live_memory) {2222 if (!dst || !max_bytes || !type_width || max_bytes < type_width)2223 return 0;2224 2225 size_t total_bytes_read = 0;2226 2227 // Ensure a null terminator independent of the number of bytes that is2228 // read.2229 memset(dst, 0, max_bytes);2230 size_t bytes_left = max_bytes - type_width;2231 2232 const char terminator[4] = {'\0', '\0', '\0', '\0'};2233 assert(sizeof(terminator) >= type_width && "Attempting to validate a "2234 "string with more than 4 bytes "2235 "per character!");2236 2237 Address address = addr;2238 char *curr_dst = dst;2239 2240 error.Clear();2241 while (bytes_left > 0 && error.Success()) {2242 addr_t bytes_to_read =2243 std::min<addr_t>(bytes_left, GetReasonableReadSize(address));2244 size_t bytes_read =2245 ReadMemory(address, curr_dst, bytes_to_read, error, force_live_memory);2246 2247 if (bytes_read == 0)2248 break;2249 2250 // Search for a null terminator of correct size and alignment in2251 // bytes_read2252 size_t aligned_start = total_bytes_read - total_bytes_read % type_width;2253 for (size_t i = aligned_start;2254 i + type_width <= total_bytes_read + bytes_read; i += type_width)2255 if (::memcmp(&dst[i], terminator, type_width) == 0) {2256 error.Clear();2257 return i;2258 }2259 2260 total_bytes_read += bytes_read;2261 curr_dst += bytes_read;2262 address.Slide(bytes_read);2263 bytes_left -= bytes_read;2264 }2265 return total_bytes_read;2266}2267 2268size_t Target::ReadScalarIntegerFromMemory(const Address &addr, uint32_t byte_size,2269 bool is_signed, Scalar &scalar,2270 Status &error,2271 bool force_live_memory) {2272 uint64_t uval;2273 2274 if (byte_size <= sizeof(uval)) {2275 size_t bytes_read =2276 ReadMemory(addr, &uval, byte_size, error, force_live_memory);2277 if (bytes_read == byte_size) {2278 DataExtractor data(&uval, sizeof(uval), m_arch.GetSpec().GetByteOrder(),2279 m_arch.GetSpec().GetAddressByteSize());2280 lldb::offset_t offset = 0;2281 if (byte_size <= 4)2282 scalar = data.GetMaxU32(&offset, byte_size);2283 else2284 scalar = data.GetMaxU64(&offset, byte_size);2285 2286 if (is_signed) {2287 scalar.MakeSigned();2288 scalar.SignExtend(byte_size * 8);2289 }2290 return bytes_read;2291 }2292 } else {2293 error = Status::FromErrorStringWithFormat(2294 "byte size of %u is too large for integer scalar type", byte_size);2295 }2296 return 0;2297}2298 2299int64_t Target::ReadSignedIntegerFromMemory(const Address &addr,2300 size_t integer_byte_size,2301 int64_t fail_value, Status &error,2302 bool force_live_memory) {2303 Scalar scalar;2304 if (ReadScalarIntegerFromMemory(addr, integer_byte_size, true, scalar, error,2305 force_live_memory))2306 return scalar.SLongLong(fail_value);2307 return fail_value;2308}2309 2310uint64_t Target::ReadUnsignedIntegerFromMemory(const Address &addr,2311 size_t integer_byte_size,2312 uint64_t fail_value, Status &error,2313 bool force_live_memory) {2314 Scalar scalar;2315 if (ReadScalarIntegerFromMemory(addr, integer_byte_size, false, scalar, error,2316 force_live_memory))2317 return scalar.ULongLong(fail_value);2318 return fail_value;2319}2320 2321bool Target::ReadPointerFromMemory(const Address &addr, Status &error,2322 Address &pointer_addr,2323 bool force_live_memory) {2324 Scalar scalar;2325 if (ReadScalarIntegerFromMemory(addr, m_arch.GetSpec().GetAddressByteSize(),2326 false, scalar, error, force_live_memory)) {2327 addr_t pointer_vm_addr = scalar.ULongLong(LLDB_INVALID_ADDRESS);2328 if (pointer_vm_addr != LLDB_INVALID_ADDRESS) {2329 SectionLoadList §ion_load_list = GetSectionLoadList();2330 if (section_load_list.IsEmpty()) {2331 // No sections are loaded, so we must assume we are not running yet and2332 // anything we are given is a file address.2333 m_images.ResolveFileAddress(pointer_vm_addr, pointer_addr);2334 } else {2335 // We have at least one section loaded. This can be because we have2336 // manually loaded some sections with "target modules load ..." or2337 // because we have a live process that has sections loaded through2338 // the dynamic loader2339 section_load_list.ResolveLoadAddress(pointer_vm_addr, pointer_addr);2340 }2341 // We weren't able to resolve the pointer value, so just return an2342 // address with no section2343 if (!pointer_addr.IsValid())2344 pointer_addr.SetOffset(pointer_vm_addr);2345 return true;2346 }2347 }2348 return false;2349}2350 2351ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec,2352 bool notify, Status *error_ptr) {2353 ModuleSP module_sp;2354 2355 Status error;2356 2357 // Apply any remappings specified in target.object-map:2358 ModuleSpec module_spec(orig_module_spec);2359 module_spec.SetTarget(shared_from_this());2360 PathMappingList &obj_mapping = GetObjectPathMap();2361 if (std::optional<FileSpec> remapped_obj_file =2362 obj_mapping.RemapPath(orig_module_spec.GetFileSpec().GetPath(),2363 true /* only_if_exists */)) {2364 module_spec.GetFileSpec().SetPath(remapped_obj_file->GetPath());2365 }2366 2367 // First see if we already have this module in our module list. If we do,2368 // then we're done, we don't need to consult the shared modules list. But2369 // only do this if we are passed a UUID.2370 2371 if (module_spec.GetUUID().IsValid())2372 module_sp = m_images.FindFirstModule(module_spec);2373 2374 if (!module_sp) {2375 llvm::SmallVector<ModuleSP, 1>2376 old_modules; // This will get filled in if we have a new version2377 // of the library2378 bool did_create_module = false;2379 FileSpecList search_paths = GetExecutableSearchPaths();2380 FileSpec symbol_file_spec;2381 2382 // Call locate module callback if set. This allows users to implement their2383 // own module cache system. For example, to leverage build system artifacts,2384 // to bypass pulling files from remote platform, or to search symbol files2385 // from symbol servers.2386 if (m_platform_sp)2387 m_platform_sp->CallLocateModuleCallbackIfSet(2388 module_spec, module_sp, symbol_file_spec, &did_create_module);2389 2390 // The result of this CallLocateModuleCallbackIfSet is one of the following.2391 // 1. module_sp:loaded, symbol_file_spec:set2392 // The callback found a module file and a symbol file for the2393 // module_spec. We will call module_sp->SetSymbolFileFileSpec with2394 // the symbol_file_spec later.2395 // 2. module_sp:loaded, symbol_file_spec:empty2396 // The callback only found a module file for the module_spec.2397 // 3. module_sp:empty, symbol_file_spec:set2398 // The callback only found a symbol file for the module. We continue2399 // to find a module file for this module_spec and we will call2400 // module_sp->SetSymbolFileFileSpec with the symbol_file_spec later.2401 // 4. module_sp:empty, symbol_file_spec:empty2402 // Platform does not exist, the callback is not set, the callback did2403 // not find any module files nor any symbol files, the callback failed,2404 // or something went wrong. We continue to find a module file for this2405 // module_spec.2406 2407 if (!module_sp) {2408 // If there are image search path entries, try to use them to acquire a2409 // suitable image.2410 if (m_image_search_paths.GetSize()) {2411 ModuleSpec transformed_spec(module_spec);2412 ConstString transformed_dir;2413 if (m_image_search_paths.RemapPath(2414 module_spec.GetFileSpec().GetDirectory(), transformed_dir)) {2415 transformed_spec.GetFileSpec().SetDirectory(transformed_dir);2416 transformed_spec.GetFileSpec().SetFilename(2417 module_spec.GetFileSpec().GetFilename());2418 transformed_spec.SetTarget(shared_from_this());2419 error = ModuleList::GetSharedModule(transformed_spec, module_sp,2420 &old_modules, &did_create_module);2421 }2422 }2423 }2424 2425 if (!module_sp) {2426 // If we have a UUID, we can check our global shared module list in case2427 // we already have it. If we don't have a valid UUID, then we can't since2428 // the path in "module_spec" will be a platform path, and we will need to2429 // let the platform find that file. For example, we could be asking for2430 // "/usr/lib/dyld" and if we do not have a UUID, we don't want to pick2431 // the local copy of "/usr/lib/dyld" since our platform could be a remote2432 // platform that has its own "/usr/lib/dyld" in an SDK or in a local file2433 // cache.2434 if (module_spec.GetUUID().IsValid()) {2435 // We have a UUID, it is OK to check the global module list...2436 error = ModuleList::GetSharedModule(module_spec, module_sp,2437 &old_modules, &did_create_module);2438 }2439 2440 if (!module_sp) {2441 // The platform is responsible for finding and caching an appropriate2442 // module in the shared module cache.2443 if (m_platform_sp) {2444 error = m_platform_sp->GetSharedModule(2445 module_spec, m_process_sp.get(), module_sp, &old_modules,2446 &did_create_module);2447 } else {2448 error = Status::FromErrorString("no platform is currently set");2449 }2450 }2451 }2452 2453 // We found a module that wasn't in our target list. Let's make sure that2454 // there wasn't an equivalent module in the list already, and if there was,2455 // let's remove it.2456 if (module_sp) {2457 ObjectFile *objfile = module_sp->GetObjectFile();2458 if (objfile) {2459 switch (objfile->GetType()) {2460 case ObjectFile::eTypeCoreFile: /// A core file that has a checkpoint of2461 /// a program's execution state2462 case ObjectFile::eTypeExecutable: /// A normal executable2463 case ObjectFile::eTypeDynamicLinker: /// The platform's dynamic linker2464 /// executable2465 case ObjectFile::eTypeObjectFile: /// An intermediate object file2466 case ObjectFile::eTypeSharedLibrary: /// A shared library that can be2467 /// used during execution2468 break;2469 case ObjectFile::eTypeDebugInfo: /// An object file that contains only2470 /// debug information2471 if (error_ptr)2472 *error_ptr = Status::FromErrorString(2473 "debug info files aren't valid target "2474 "modules, please specify an executable");2475 return ModuleSP();2476 case ObjectFile::eTypeStubLibrary: /// A library that can be linked2477 /// against but not used for2478 /// execution2479 if (error_ptr)2480 *error_ptr = Status::FromErrorString(2481 "stub libraries aren't valid target "2482 "modules, please specify an executable");2483 return ModuleSP();2484 default:2485 if (error_ptr)2486 *error_ptr = Status::FromErrorString(2487 "unsupported file type, please specify an executable");2488 return ModuleSP();2489 }2490 // GetSharedModule is not guaranteed to find the old shared module, for2491 // instance in the common case where you pass in the UUID, it is only2492 // going to find the one module matching the UUID. In fact, it has no2493 // good way to know what the "old module" relevant to this target is,2494 // since there might be many copies of a module with this file spec in2495 // various running debug sessions, but only one of them will belong to2496 // this target. So let's remove the UUID from the module list, and look2497 // in the target's module list. Only do this if there is SOMETHING else2498 // in the module spec...2499 if (module_spec.GetUUID().IsValid() &&2500 !module_spec.GetFileSpec().GetFilename().IsEmpty() &&2501 !module_spec.GetFileSpec().GetDirectory().IsEmpty()) {2502 ModuleSpec module_spec_copy(module_spec.GetFileSpec());2503 module_spec_copy.GetUUID().Clear();2504 2505 ModuleList found_modules;2506 m_images.FindModules(module_spec_copy, found_modules);2507 found_modules.ForEach([&](const ModuleSP &found_module) {2508 old_modules.push_back(found_module);2509 return IterationAction::Continue;2510 });2511 }2512 2513 // If the locate module callback had found a symbol file, set it to the2514 // module_sp before preloading symbols.2515 if (symbol_file_spec)2516 module_sp->SetSymbolFileFileSpec(symbol_file_spec);2517 2518 llvm::SmallVector<ModuleSP, 1> replaced_modules;2519 for (ModuleSP &old_module_sp : old_modules) {2520 if (m_images.GetIndexForModule(old_module_sp.get()) !=2521 LLDB_INVALID_INDEX32) {2522 if (replaced_modules.empty())2523 m_images.ReplaceModule(old_module_sp, module_sp);2524 else2525 m_images.Remove(old_module_sp);2526 2527 replaced_modules.push_back(std::move(old_module_sp));2528 }2529 }2530 2531 if (replaced_modules.size() > 1) {2532 // The same new module replaced multiple old modules2533 // simultaneously. It's not clear this should ever2534 // happen (if we always replace old modules as we add2535 // new ones, presumably we should never have more than2536 // one old one). If there are legitimate cases where2537 // this happens, then the ModuleList::Notifier interface2538 // may need to be adjusted to allow reporting this.2539 // In the meantime, just log that this has happened; just2540 // above we called ReplaceModule on the first one, and Remove2541 // on the rest.2542 if (Log *log = GetLog(LLDBLog::Target | LLDBLog::Modules)) {2543 StreamString message;2544 auto dump = [&message](Module &dump_module) -> void {2545 UUID dump_uuid = dump_module.GetUUID();2546 2547 message << '[';2548 dump_module.GetDescription(message.AsRawOstream());2549 message << " (uuid ";2550 2551 if (dump_uuid.IsValid())2552 dump_uuid.Dump(message);2553 else2554 message << "not specified";2555 2556 message << ")]";2557 };2558 2559 message << "New module ";2560 dump(*module_sp);2561 message.AsRawOstream()2562 << llvm::formatv(" simultaneously replaced {0} old modules: ",2563 replaced_modules.size());2564 for (ModuleSP &replaced_module_sp : replaced_modules)2565 dump(*replaced_module_sp);2566 2567 log->PutString(message.GetString());2568 }2569 }2570 2571 if (replaced_modules.empty())2572 m_images.Append(module_sp, notify);2573 2574 for (ModuleSP &old_module_sp : replaced_modules) {2575 auto old_module_wp = old_module_sp->weak_from_this();2576 old_module_sp.reset();2577 ModuleList::RemoveSharedModuleIfOrphaned(old_module_wp);2578 }2579 } else2580 module_sp.reset();2581 }2582 }2583 if (error_ptr)2584 *error_ptr = std::move(error);2585 return module_sp;2586}2587 2588TargetSP Target::CalculateTarget() { return shared_from_this(); }2589 2590ProcessSP Target::CalculateProcess() { return m_process_sp; }2591 2592ThreadSP Target::CalculateThread() { return ThreadSP(); }2593 2594StackFrameSP Target::CalculateStackFrame() { return StackFrameSP(); }2595 2596void Target::CalculateExecutionContext(ExecutionContext &exe_ctx) {2597 exe_ctx.Clear();2598 exe_ctx.SetTargetPtr(this);2599}2600 2601PathMappingList &Target::GetImageSearchPathList() {2602 return m_image_search_paths;2603}2604 2605void Target::ImageSearchPathsChanged(const PathMappingList &path_list,2606 void *baton) {2607 Target *target = (Target *)baton;2608 ModuleSP exe_module_sp(target->GetExecutableModule());2609 if (exe_module_sp)2610 target->SetExecutableModule(exe_module_sp, eLoadDependentsYes);2611}2612 2613llvm::Expected<lldb::TypeSystemSP>2614Target::GetScratchTypeSystemForLanguage(lldb::LanguageType language,2615 bool create_on_demand) {2616 if (!m_valid)2617 return llvm::createStringError("Invalid Target");2618 2619 if (language == eLanguageTypeMipsAssembler // GNU AS and LLVM use it for all2620 // assembly code2621 || language == eLanguageTypeUnknown) {2622 LanguageSet languages_for_expressions =2623 Language::GetLanguagesSupportingTypeSystemsForExpressions();2624 2625 if (languages_for_expressions[eLanguageTypeC]) {2626 language = eLanguageTypeC; // LLDB's default. Override by setting the2627 // target language.2628 } else {2629 if (languages_for_expressions.Empty())2630 return llvm::createStringError(2631 "No expression support for any languages");2632 language = (LanguageType)languages_for_expressions.bitvector.find_first();2633 }2634 }2635 2636 return m_scratch_type_system_map.GetTypeSystemForLanguage(language, this,2637 create_on_demand);2638}2639 2640CompilerType Target::GetRegisterType(const std::string &name,2641 const lldb_private::RegisterFlags &flags,2642 uint32_t byte_size) {2643 RegisterTypeBuilderSP provider = PluginManager::GetRegisterTypeBuilder(*this);2644 assert(provider);2645 return provider->GetRegisterType(name, flags, byte_size);2646}2647 2648std::vector<lldb::TypeSystemSP>2649Target::GetScratchTypeSystems(bool create_on_demand) {2650 if (!m_valid)2651 return {};2652 2653 // Some TypeSystem instances are associated with several LanguageTypes so2654 // they will show up several times in the loop below. The SetVector filters2655 // out all duplicates as they serve no use for the caller.2656 std::vector<lldb::TypeSystemSP> scratch_type_systems;2657 2658 LanguageSet languages_for_expressions =2659 Language::GetLanguagesSupportingTypeSystemsForExpressions();2660 2661 for (auto bit : languages_for_expressions.bitvector.set_bits()) {2662 auto language = (LanguageType)bit;2663 auto type_system_or_err =2664 GetScratchTypeSystemForLanguage(language, create_on_demand);2665 if (!type_system_or_err)2666 LLDB_LOG_ERROR(2667 GetLog(LLDBLog::Target), type_system_or_err.takeError(),2668 "Language '{1}' has expression support but no scratch type "2669 "system available: {0}",2670 Language::GetNameForLanguageType(language));2671 else2672 if (auto ts = *type_system_or_err)2673 scratch_type_systems.push_back(ts);2674 }2675 2676 std::sort(scratch_type_systems.begin(), scratch_type_systems.end());2677 scratch_type_systems.erase(llvm::unique(scratch_type_systems),2678 scratch_type_systems.end());2679 return scratch_type_systems;2680}2681 2682PersistentExpressionState *2683Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) {2684 auto type_system_or_err = GetScratchTypeSystemForLanguage(language, true);2685 2686 if (auto err = type_system_or_err.takeError()) {2687 LLDB_LOG_ERROR(2688 GetLog(LLDBLog::Target), std::move(err),2689 "Unable to get persistent expression state for language {1}: {0}",2690 Language::GetNameForLanguageType(language));2691 return nullptr;2692 }2693 2694 if (auto ts = *type_system_or_err)2695 return ts->GetPersistentExpressionState();2696 2697 LLDB_LOG(GetLog(LLDBLog::Target),2698 "Unable to get persistent expression state for language {1}: {0}",2699 Language::GetNameForLanguageType(language));2700 return nullptr;2701}2702 2703UserExpression *Target::GetUserExpressionForLanguage(2704 llvm::StringRef expr, llvm::StringRef prefix, SourceLanguage language,2705 Expression::ResultType desired_type,2706 const EvaluateExpressionOptions &options, ValueObject *ctx_obj,2707 Status &error) {2708 auto type_system_or_err =2709 GetScratchTypeSystemForLanguage(language.AsLanguageType());2710 if (auto err = type_system_or_err.takeError()) {2711 error = Status::FromErrorStringWithFormat(2712 "Could not find type system for language %s: %s",2713 Language::GetNameForLanguageType(language.AsLanguageType()),2714 llvm::toString(std::move(err)).c_str());2715 return nullptr;2716 }2717 2718 auto ts = *type_system_or_err;2719 if (!ts) {2720 error = Status::FromErrorStringWithFormat(2721 "Type system for language %s is no longer live",2722 language.GetDescription().data());2723 return nullptr;2724 }2725 2726 auto *user_expr = ts->GetUserExpression(expr, prefix, language, desired_type,2727 options, ctx_obj);2728 if (!user_expr)2729 error = Status::FromErrorStringWithFormat(2730 "Could not create an expression for language %s",2731 language.GetDescription().data());2732 2733 return user_expr;2734}2735 2736FunctionCaller *Target::GetFunctionCallerForLanguage(2737 lldb::LanguageType language, const CompilerType &return_type,2738 const Address &function_address, const ValueList &arg_value_list,2739 const char *name, Status &error) {2740 auto type_system_or_err = GetScratchTypeSystemForLanguage(language);2741 if (auto err = type_system_or_err.takeError()) {2742 error = Status::FromErrorStringWithFormat(2743 "Could not find type system for language %s: %s",2744 Language::GetNameForLanguageType(language),2745 llvm::toString(std::move(err)).c_str());2746 return nullptr;2747 }2748 auto ts = *type_system_or_err;2749 if (!ts) {2750 error = Status::FromErrorStringWithFormat(2751 "Type system for language %s is no longer live",2752 Language::GetNameForLanguageType(language));2753 return nullptr;2754 }2755 auto *persistent_fn = ts->GetFunctionCaller(return_type, function_address,2756 arg_value_list, name);2757 if (!persistent_fn)2758 error = Status::FromErrorStringWithFormat(2759 "Could not create an expression for language %s",2760 Language::GetNameForLanguageType(language));2761 2762 return persistent_fn;2763}2764 2765llvm::Expected<std::unique_ptr<UtilityFunction>>2766Target::CreateUtilityFunction(std::string expression, std::string name,2767 lldb::LanguageType language,2768 ExecutionContext &exe_ctx) {2769 auto type_system_or_err = GetScratchTypeSystemForLanguage(language);2770 if (!type_system_or_err)2771 return type_system_or_err.takeError();2772 auto ts = *type_system_or_err;2773 if (!ts)2774 return llvm::createStringError(2775 llvm::StringRef("Type system for language ") +2776 Language::GetNameForLanguageType(language) +2777 llvm::StringRef(" is no longer live"));2778 std::unique_ptr<UtilityFunction> utility_fn =2779 ts->CreateUtilityFunction(std::move(expression), std::move(name));2780 if (!utility_fn)2781 return llvm::createStringError(2782 llvm::StringRef("Could not create an expression for language") +2783 Language::GetNameForLanguageType(language));2784 2785 DiagnosticManager diagnostics;2786 if (!utility_fn->Install(diagnostics, exe_ctx))2787 return diagnostics.GetAsError(lldb::eExpressionSetupError,2788 "Could not install utility function:");2789 2790 return std::move(utility_fn);2791}2792 2793void Target::SettingsInitialize() { Process::SettingsInitialize(); }2794 2795void Target::SettingsTerminate() { Process::SettingsTerminate(); }2796 2797FileSpecList Target::GetDefaultExecutableSearchPaths() {2798 return Target::GetGlobalProperties().GetExecutableSearchPaths();2799}2800 2801FileSpecList Target::GetDefaultDebugFileSearchPaths() {2802 return Target::GetGlobalProperties().GetDebugFileSearchPaths();2803}2804 2805ArchSpec Target::GetDefaultArchitecture() {2806 return Target::GetGlobalProperties().GetDefaultArchitecture();2807}2808 2809void Target::SetDefaultArchitecture(const ArchSpec &arch) {2810 LLDB_LOG(GetLog(LLDBLog::Target),2811 "setting target's default architecture to {0} ({1})",2812 arch.GetArchitectureName(), arch.GetTriple().getTriple());2813 Target::GetGlobalProperties().SetDefaultArchitecture(arch);2814}2815 2816llvm::Error Target::SetLabel(llvm::StringRef label) {2817 size_t n = LLDB_INVALID_INDEX32;2818 if (llvm::to_integer(label, n))2819 return llvm::createStringError("Cannot use integer as target label.");2820 TargetList &targets = GetDebugger().GetTargetList();2821 for (size_t i = 0; i < targets.GetNumTargets(); i++) {2822 TargetSP target_sp = targets.GetTargetAtIndex(i);2823 if (target_sp && target_sp->GetLabel() == label) {2824 return llvm::make_error<llvm::StringError>(2825 llvm::formatv(2826 "Cannot use label '{0}' since it's set in target #{1}.", label,2827 i),2828 llvm::inconvertibleErrorCode());2829 }2830 }2831 2832 m_label = label.str();2833 return llvm::Error::success();2834}2835 2836Target *Target::GetTargetFromContexts(const ExecutionContext *exe_ctx_ptr,2837 const SymbolContext *sc_ptr) {2838 // The target can either exist in the "process" of ExecutionContext, or in2839 // the "target_sp" member of SymbolContext. This accessor helper function2840 // will get the target from one of these locations.2841 2842 Target *target = nullptr;2843 if (sc_ptr != nullptr)2844 target = sc_ptr->target_sp.get();2845 if (target == nullptr && exe_ctx_ptr)2846 target = exe_ctx_ptr->GetTargetPtr();2847 return target;2848}2849 2850ExpressionResults Target::EvaluateExpression(2851 llvm::StringRef expr, ExecutionContextScope *exe_scope,2852 lldb::ValueObjectSP &result_valobj_sp,2853 const EvaluateExpressionOptions &options, std::string *fixed_expression,2854 ValueObject *ctx_obj) {2855 result_valobj_sp.reset();2856 2857 ExpressionResults execution_results = eExpressionSetupError;2858 2859 if (expr.empty()) {2860 m_stats.GetExpressionStats().NotifyFailure();2861 return execution_results;2862 }2863 2864 // We shouldn't run stop hooks in expressions.2865 bool old_suppress_value = m_suppress_stop_hooks;2866 m_suppress_stop_hooks = true;2867 auto on_exit = llvm::make_scope_exit([this, old_suppress_value]() {2868 m_suppress_stop_hooks = old_suppress_value;2869 });2870 2871 ExecutionContext exe_ctx;2872 2873 if (exe_scope) {2874 exe_scope->CalculateExecutionContext(exe_ctx);2875 } else if (m_process_sp) {2876 m_process_sp->CalculateExecutionContext(exe_ctx);2877 } else {2878 CalculateExecutionContext(exe_ctx);2879 }2880 2881 // Make sure we aren't just trying to see the value of a persistent variable2882 // (something like "$0")2883 // Only check for persistent variables the expression starts with a '$'2884 lldb::ExpressionVariableSP persistent_var_sp;2885 if (expr[0] == '$') {2886 auto type_system_or_err =2887 GetScratchTypeSystemForLanguage(eLanguageTypeC);2888 if (auto err = type_system_or_err.takeError()) {2889 LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err),2890 "Unable to get scratch type system");2891 } else {2892 auto ts = *type_system_or_err;2893 if (!ts)2894 LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err),2895 "Scratch type system is no longer live: {0}");2896 else2897 persistent_var_sp =2898 ts->GetPersistentExpressionState()->GetVariable(expr);2899 }2900 }2901 if (persistent_var_sp) {2902 result_valobj_sp = persistent_var_sp->GetValueObject();2903 execution_results = eExpressionCompleted;2904 } else {2905 llvm::StringRef prefix = GetExpressionPrefixContents();2906 execution_results =2907 UserExpression::Evaluate(exe_ctx, options, expr, prefix,2908 result_valobj_sp, fixed_expression, ctx_obj);2909 }2910 2911 if (execution_results == eExpressionCompleted)2912 m_stats.GetExpressionStats().NotifySuccess();2913 else2914 m_stats.GetExpressionStats().NotifyFailure();2915 return execution_results;2916}2917 2918lldb::ExpressionVariableSP Target::GetPersistentVariable(ConstString name) {2919 lldb::ExpressionVariableSP variable_sp;2920 m_scratch_type_system_map.ForEach(2921 [name, &variable_sp](TypeSystemSP type_system) -> bool {2922 auto ts = type_system.get();2923 if (!ts)2924 return true;2925 if (PersistentExpressionState *persistent_state =2926 ts->GetPersistentExpressionState()) {2927 variable_sp = persistent_state->GetVariable(name);2928 2929 if (variable_sp)2930 return false; // Stop iterating the ForEach2931 }2932 return true; // Keep iterating the ForEach2933 });2934 return variable_sp;2935}2936 2937lldb::addr_t Target::GetPersistentSymbol(ConstString name) {2938 lldb::addr_t address = LLDB_INVALID_ADDRESS;2939 2940 m_scratch_type_system_map.ForEach(2941 [name, &address](lldb::TypeSystemSP type_system) -> bool {2942 auto ts = type_system.get();2943 if (!ts)2944 return true;2945 2946 if (PersistentExpressionState *persistent_state =2947 ts->GetPersistentExpressionState()) {2948 address = persistent_state->LookupSymbol(name);2949 if (address != LLDB_INVALID_ADDRESS)2950 return false; // Stop iterating the ForEach2951 }2952 return true; // Keep iterating the ForEach2953 });2954 return address;2955}2956 2957llvm::Expected<lldb_private::Address> Target::GetEntryPointAddress() {2958 Module *exe_module = GetExecutableModulePointer();2959 2960 // Try to find the entry point address in the primary executable.2961 const bool has_primary_executable = exe_module && exe_module->GetObjectFile();2962 if (has_primary_executable) {2963 Address entry_addr = exe_module->GetObjectFile()->GetEntryPointAddress();2964 if (entry_addr.IsValid())2965 return entry_addr;2966 }2967 2968 const ModuleList &modules = GetImages();2969 const size_t num_images = modules.GetSize();2970 for (size_t idx = 0; idx < num_images; ++idx) {2971 ModuleSP module_sp(modules.GetModuleAtIndex(idx));2972 if (!module_sp || !module_sp->GetObjectFile())2973 continue;2974 2975 Address entry_addr = module_sp->GetObjectFile()->GetEntryPointAddress();2976 if (entry_addr.IsValid())2977 return entry_addr;2978 }2979 2980 // We haven't found the entry point address. Return an appropriate error.2981 if (!has_primary_executable)2982 return llvm::createStringError(2983 "No primary executable found and could not find entry point address in "2984 "any executable module");2985 2986 return llvm::createStringError(2987 "Could not find entry point address for primary executable module \"" +2988 exe_module->GetFileSpec().GetFilename().GetStringRef() + "\"");2989}2990 2991lldb::addr_t Target::GetCallableLoadAddress(lldb::addr_t load_addr,2992 AddressClass addr_class) const {2993 auto arch_plugin = GetArchitecturePlugin();2994 return arch_plugin2995 ? arch_plugin->GetCallableLoadAddress(load_addr, addr_class)2996 : load_addr;2997}2998 2999lldb::addr_t Target::GetOpcodeLoadAddress(lldb::addr_t load_addr,3000 AddressClass addr_class) const {3001 auto arch_plugin = GetArchitecturePlugin();3002 return arch_plugin ? arch_plugin->GetOpcodeLoadAddress(load_addr, addr_class)3003 : load_addr;3004}3005 3006lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) {3007 auto arch_plugin = GetArchitecturePlugin();3008 return arch_plugin ? arch_plugin->GetBreakableLoadAddress(addr, *this) : addr;3009}3010 3011llvm::Expected<lldb::DisassemblerSP>3012Target::ReadInstructions(const Address &start_addr, uint32_t count,3013 const char *flavor_string) {3014 DataBufferHeap data(GetArchitecture().GetMaximumOpcodeByteSize() * count, 0);3015 bool force_live_memory = true;3016 lldb_private::Status error;3017 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;3018 const size_t bytes_read =3019 ReadMemory(start_addr, data.GetBytes(), data.GetByteSize(), error,3020 force_live_memory, &load_addr);3021 3022 if (error.Fail())3023 return llvm::createStringError(3024 error.AsCString("Target::ReadInstructions failed to read memory at %s"),3025 start_addr.GetLoadAddress(this));3026 3027 const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;3028 if (!flavor_string || flavor_string[0] == '\0') {3029 // FIXME - we don't have the mechanism in place to do per-architecture3030 // settings. But since we know that for now we only support flavors on3031 // x86 & x86_64,3032 const llvm::Triple::ArchType arch = GetArchitecture().GetTriple().getArch();3033 if (arch == llvm::Triple::x86 || arch == llvm::Triple::x86_64)3034 flavor_string = GetDisassemblyFlavor();3035 }3036 3037 return Disassembler::DisassembleBytes(3038 GetArchitecture(), nullptr, flavor_string, GetDisassemblyCPU(),3039 GetDisassemblyFeatures(), start_addr, data.GetBytes(), bytes_read, count,3040 data_from_file);3041}3042 3043SourceManager &Target::GetSourceManager() {3044 if (!m_source_manager_up)3045 m_source_manager_up = std::make_unique<SourceManager>(shared_from_this());3046 return *m_source_manager_up;3047}3048 3049Target::StopHookSP Target::CreateStopHook(StopHook::StopHookKind kind,3050 bool internal) {3051 user_id_t new_uid = (internal ? LLDB_INVALID_UID : ++m_stop_hook_next_id);3052 Target::StopHookSP stop_hook_sp;3053 switch (kind) {3054 case StopHook::StopHookKind::CommandBased:3055 stop_hook_sp.reset(new StopHookCommandLine(shared_from_this(), new_uid));3056 break;3057 case StopHook::StopHookKind::ScriptBased:3058 stop_hook_sp.reset(new StopHookScripted(shared_from_this(), new_uid));3059 break;3060 case StopHook::StopHookKind::CodeBased:3061 stop_hook_sp.reset(new StopHookCoded(shared_from_this(), new_uid));3062 break;3063 }3064 if (internal)3065 m_internal_stop_hooks.push_back(stop_hook_sp);3066 else3067 m_stop_hooks[new_uid] = stop_hook_sp;3068 return stop_hook_sp;3069}3070 3071void Target::UndoCreateStopHook(lldb::user_id_t user_id) {3072 if (!RemoveStopHookByID(user_id))3073 return;3074 if (user_id == m_stop_hook_next_id)3075 m_stop_hook_next_id--;3076}3077 3078bool Target::RemoveStopHookByID(lldb::user_id_t user_id) {3079 size_t num_removed = m_stop_hooks.erase(user_id);3080 return (num_removed != 0);3081}3082 3083void Target::RemoveAllStopHooks() { m_stop_hooks.clear(); }3084 3085Target::StopHookSP Target::GetStopHookByID(lldb::user_id_t user_id) {3086 StopHookSP found_hook;3087 3088 StopHookCollection::iterator specified_hook_iter;3089 specified_hook_iter = m_stop_hooks.find(user_id);3090 if (specified_hook_iter != m_stop_hooks.end())3091 found_hook = (*specified_hook_iter).second;3092 return found_hook;3093}3094 3095bool Target::SetStopHookActiveStateByID(lldb::user_id_t user_id,3096 bool active_state) {3097 StopHookCollection::iterator specified_hook_iter;3098 specified_hook_iter = m_stop_hooks.find(user_id);3099 if (specified_hook_iter == m_stop_hooks.end())3100 return false;3101 3102 (*specified_hook_iter).second->SetIsActive(active_state);3103 return true;3104}3105 3106void Target::SetAllStopHooksActiveState(bool active_state) {3107 StopHookCollection::iterator pos, end = m_stop_hooks.end();3108 for (pos = m_stop_hooks.begin(); pos != end; pos++) {3109 (*pos).second->SetIsActive(active_state);3110 }3111}3112 3113// FIXME: Ideally we would like to return a `const &` (const reference) instead3114// of creating copy here, but that is not possible due to different container3115// types. In C++20, we should be able to use `std::ranges::views::values` to3116// adapt the key-pair entries in the `std::map` (behind `StopHookCollection`)3117// to avoid creating the copy.3118const std::vector<Target::StopHookSP>3119Target::GetStopHooks(bool internal) const {3120 if (internal)3121 return m_internal_stop_hooks;3122 3123 std::vector<StopHookSP> stop_hooks;3124 for (auto &[_, hook] : m_stop_hooks)3125 stop_hooks.push_back(hook);3126 3127 return stop_hooks;3128}3129 3130bool Target::RunStopHooks(bool at_initial_stop) {3131 if (m_suppress_stop_hooks)3132 return false;3133 3134 if (!m_process_sp)3135 return false;3136 3137 // Somebody might have restarted the process:3138 // Still return false, the return value is about US restarting the target.3139 lldb::StateType state = m_process_sp->GetState();3140 if (!(state == eStateStopped || state == eStateAttaching))3141 return false;3142 3143 auto is_active = [at_initial_stop](StopHookSP hook) {3144 bool should_run_now = (!at_initial_stop || hook->GetRunAtInitialStop());3145 return hook->IsActive() && should_run_now;3146 };3147 3148 // Create list of active internal and user stop hooks.3149 std::vector<StopHookSP> active_hooks;3150 llvm::copy_if(m_internal_stop_hooks, std::back_inserter(active_hooks),3151 is_active);3152 for (auto &[_, hook] : m_stop_hooks) {3153 if (is_active(hook))3154 active_hooks.push_back(hook);3155 }3156 if (active_hooks.empty())3157 return false;3158 3159 // Make sure we check that we are not stopped because of us running a user3160 // expression since in that case we do not want to run the stop-hooks. Note,3161 // you can't just check whether the last stop was for a User Expression,3162 // because breakpoint commands get run before stop hooks, and one of them3163 // might have run an expression. You have to ensure you run the stop hooks3164 // once per natural stop.3165 uint32_t last_natural_stop = m_process_sp->GetModIDRef().GetLastNaturalStopID();3166 if (last_natural_stop != 0 && m_latest_stop_hook_id == last_natural_stop)3167 return false;3168 3169 m_latest_stop_hook_id = last_natural_stop;3170 3171 std::vector<ExecutionContext> exc_ctx_with_reasons;3172 3173 ThreadList &cur_threadlist = m_process_sp->GetThreadList();3174 size_t num_threads = cur_threadlist.GetSize();3175 for (size_t i = 0; i < num_threads; i++) {3176 lldb::ThreadSP cur_thread_sp = cur_threadlist.GetThreadAtIndex(i);3177 if (cur_thread_sp->ThreadStoppedForAReason()) {3178 lldb::StackFrameSP cur_frame_sp = cur_thread_sp->GetStackFrameAtIndex(0);3179 exc_ctx_with_reasons.emplace_back(m_process_sp.get(), cur_thread_sp.get(),3180 cur_frame_sp.get());3181 }3182 }3183 3184 // If no threads stopped for a reason, don't run the stop-hooks.3185 // However, if this is the FIRST stop for this process, then we are in the3186 // state where an attach or a core file load was completed without designating3187 // a particular thread as responsible for the stop. In that case, we do3188 // want to run the stop hooks, but do so just on one thread.3189 size_t num_exe_ctx = exc_ctx_with_reasons.size();3190 if (num_exe_ctx == 0) {3191 if (at_initial_stop && num_threads > 0) {3192 lldb::ThreadSP thread_to_use_sp = cur_threadlist.GetThreadAtIndex(0);3193 exc_ctx_with_reasons.emplace_back(3194 m_process_sp.get(), thread_to_use_sp.get(),3195 thread_to_use_sp->GetStackFrameAtIndex(0).get());3196 num_exe_ctx = 1;3197 } else {3198 return false;3199 }3200 }3201 3202 StreamSP output_sp = m_debugger.GetAsyncOutputStream();3203 auto on_exit = llvm::make_scope_exit([output_sp] { output_sp->Flush(); });3204 3205 size_t num_hooks_with_output = llvm::count_if(3206 active_hooks, [](auto h) { return !h->GetSuppressOutput(); });3207 bool print_hook_header = (num_hooks_with_output > 1);3208 bool print_thread_header = (num_exe_ctx > 1);3209 bool should_stop = false;3210 bool requested_continue = false;3211 3212 // A stop hook might get deleted while running stop hooks.3213 // We have to decide what that means. We will follow the rule that deleting3214 // a stop hook while processing these stop hooks will delete it for FUTURE3215 // stops but not this stop. Fortunately, copying the m_stop_hooks to the3216 // active_hooks list before iterating over the hooks has this effect.3217 for (auto cur_hook_sp : active_hooks) {3218 bool any_thread_matched = false;3219 for (auto exc_ctx : exc_ctx_with_reasons) {3220 if (!cur_hook_sp->ExecutionContextPasses(exc_ctx))3221 continue;3222 3223 bool suppress_output = cur_hook_sp->GetSuppressOutput();3224 if (print_hook_header && !any_thread_matched && !suppress_output) {3225 StreamString s;3226 cur_hook_sp->GetDescription(s, eDescriptionLevelBrief);3227 if (s.GetSize() != 0)3228 output_sp->Printf("\n- Hook %" PRIu64 " (%s)\n", cur_hook_sp->GetID(),3229 s.GetData());3230 else3231 output_sp->Printf("\n- Hook %" PRIu64 "\n", cur_hook_sp->GetID());3232 any_thread_matched = true;3233 }3234 3235 if (print_thread_header && !suppress_output)3236 output_sp->Printf("-- Thread %d\n",3237 exc_ctx.GetThreadPtr()->GetIndexID());3238 3239 auto result = cur_hook_sp->HandleStop(exc_ctx, output_sp);3240 switch (result) {3241 case StopHook::StopHookResult::KeepStopped:3242 if (cur_hook_sp->GetAutoContinue())3243 requested_continue = true;3244 else3245 should_stop = true;3246 break;3247 case StopHook::StopHookResult::RequestContinue:3248 requested_continue = true;3249 break;3250 case StopHook::StopHookResult::NoPreference:3251 // Do nothing3252 break;3253 case StopHook::StopHookResult::AlreadyContinued:3254 // We don't have a good way to prohibit people from restarting the3255 // target willy nilly in a stop hook. If the hook did so, give a3256 // gentle suggestion here and back out of the hook processing.3257 output_sp->Printf("\nAborting stop hooks, hook %" PRIu643258 " set the program running.\n"3259 " Consider using '-G true' to make "3260 "stop hooks auto-continue.\n",3261 cur_hook_sp->GetID());3262 // FIXME: if we are doing non-stop mode for real, we would have to3263 // check that OUR thread was restarted, otherwise we should keep3264 // processing stop hooks.3265 return true;3266 }3267 }3268 }3269 3270 // Resume iff at least one hook requested to continue and no hook asked to3271 // stop.3272 if (requested_continue && !should_stop) {3273 Log *log = GetLog(LLDBLog::Process);3274 Status error = m_process_sp->PrivateResume();3275 if (error.Success()) {3276 LLDB_LOG(log, "Resuming from RunStopHooks");3277 return true;3278 } else {3279 LLDB_LOG(log, "Resuming from RunStopHooks failed: {0}", error);3280 return false;3281 }3282 }3283 3284 return false;3285}3286 3287TargetProperties &Target::GetGlobalProperties() {3288 // NOTE: intentional leak so we don't crash if global destructor chain gets3289 // called as other threads still use the result of this function3290 static TargetProperties *g_settings_ptr =3291 new TargetProperties(nullptr);3292 return *g_settings_ptr;3293}3294 3295Status Target::Install(ProcessLaunchInfo *launch_info) {3296 Status error;3297 PlatformSP platform_sp(GetPlatform());3298 if (!platform_sp || !platform_sp->IsRemote() || !platform_sp->IsConnected())3299 return error;3300 3301 // Install all files that have an install path when connected to a3302 // remote platform. If target.auto-install-main-executable is set then3303 // also install the main executable even if it does not have an explicit3304 // install path specified.3305 3306 for (auto module_sp : GetImages().Modules()) {3307 if (module_sp == GetExecutableModule()) {3308 MainExecutableInstaller installer{platform_sp, module_sp,3309 shared_from_this(), *launch_info};3310 error = installExecutable(installer);3311 } else {3312 ExecutableInstaller installer{platform_sp, module_sp};3313 error = installExecutable(installer);3314 }3315 3316 if (error.Fail())3317 return error;3318 }3319 3320 return error;3321}3322 3323bool Target::ResolveLoadAddress(addr_t load_addr, Address &so_addr,3324 uint32_t stop_id, bool allow_section_end) {3325 return m_section_load_history.ResolveLoadAddress(stop_id, load_addr, so_addr,3326 allow_section_end);3327}3328 3329bool Target::ResolveFileAddress(lldb::addr_t file_addr,3330 Address &resolved_addr) {3331 return m_images.ResolveFileAddress(file_addr, resolved_addr);3332}3333 3334bool Target::SetSectionLoadAddress(const SectionSP §ion_sp,3335 addr_t new_section_load_addr,3336 bool warn_multiple) {3337 const addr_t old_section_load_addr =3338 m_section_load_history.GetSectionLoadAddress(3339 SectionLoadHistory::eStopIDNow, section_sp);3340 if (old_section_load_addr != new_section_load_addr) {3341 uint32_t stop_id = 0;3342 ProcessSP process_sp(GetProcessSP());3343 if (process_sp)3344 stop_id = process_sp->GetStopID();3345 else3346 stop_id = m_section_load_history.GetLastStopID();3347 if (m_section_load_history.SetSectionLoadAddress(3348 stop_id, section_sp, new_section_load_addr, warn_multiple))3349 return true; // Return true if the section load address was changed...3350 }3351 return false; // Return false to indicate nothing changed3352}3353 3354size_t Target::UnloadModuleSections(const ModuleList &module_list) {3355 size_t section_unload_count = 0;3356 size_t num_modules = module_list.GetSize();3357 for (size_t i = 0; i < num_modules; ++i) {3358 section_unload_count +=3359 UnloadModuleSections(module_list.GetModuleAtIndex(i));3360 }3361 return section_unload_count;3362}3363 3364size_t Target::UnloadModuleSections(const lldb::ModuleSP &module_sp) {3365 uint32_t stop_id = 0;3366 ProcessSP process_sp(GetProcessSP());3367 if (process_sp)3368 stop_id = process_sp->GetStopID();3369 else3370 stop_id = m_section_load_history.GetLastStopID();3371 SectionList *sections = module_sp->GetSectionList();3372 size_t section_unload_count = 0;3373 if (sections) {3374 const uint32_t num_sections = sections->GetNumSections(0);3375 for (uint32_t i = 0; i < num_sections; ++i) {3376 section_unload_count += m_section_load_history.SetSectionUnloaded(3377 stop_id, sections->GetSectionAtIndex(i));3378 }3379 }3380 return section_unload_count;3381}3382 3383bool Target::SetSectionUnloaded(const lldb::SectionSP §ion_sp) {3384 uint32_t stop_id = 0;3385 ProcessSP process_sp(GetProcessSP());3386 if (process_sp)3387 stop_id = process_sp->GetStopID();3388 else3389 stop_id = m_section_load_history.GetLastStopID();3390 return m_section_load_history.SetSectionUnloaded(stop_id, section_sp);3391}3392 3393bool Target::SetSectionUnloaded(const lldb::SectionSP §ion_sp,3394 addr_t load_addr) {3395 uint32_t stop_id = 0;3396 ProcessSP process_sp(GetProcessSP());3397 if (process_sp)3398 stop_id = process_sp->GetStopID();3399 else3400 stop_id = m_section_load_history.GetLastStopID();3401 return m_section_load_history.SetSectionUnloaded(stop_id, section_sp,3402 load_addr);3403}3404 3405void Target::ClearAllLoadedSections() { m_section_load_history.Clear(); }3406 3407lldb_private::SummaryStatisticsSP Target::GetSummaryStatisticsSPForProviderName(3408 lldb_private::TypeSummaryImpl &summary_provider) {3409 return m_summary_statistics_cache.GetSummaryStatisticsForProvider(3410 summary_provider);3411}3412 3413SummaryStatisticsCache &Target::GetSummaryStatisticsCache() {3414 return m_summary_statistics_cache;3415}3416 3417void Target::SaveScriptedLaunchInfo(lldb_private::ProcessInfo &process_info) {3418 if (process_info.IsScriptedProcess()) {3419 // Only copy scripted process launch options.3420 ProcessLaunchInfo &default_launch_info = const_cast<ProcessLaunchInfo &>(3421 GetGlobalProperties().GetProcessLaunchInfo());3422 default_launch_info.SetProcessPluginName("ScriptedProcess");3423 default_launch_info.SetScriptedMetadata(process_info.GetScriptedMetadata());3424 SetProcessLaunchInfo(default_launch_info);3425 }3426}3427 3428Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {3429 m_stats.SetLaunchOrAttachTime();3430 Status error;3431 Log *log = GetLog(LLDBLog::Target);3432 3433 LLDB_LOGF(log, "Target::%s() called for %s", __FUNCTION__,3434 launch_info.GetExecutableFile().GetPath().c_str());3435 3436 StateType state = eStateInvalid;3437 3438 // Scope to temporarily get the process state in case someone has manually3439 // remotely connected already to a process and we can skip the platform3440 // launching.3441 {3442 ProcessSP process_sp(GetProcessSP());3443 3444 if (process_sp) {3445 state = process_sp->GetState();3446 LLDB_LOGF(log,3447 "Target::%s the process exists, and its current state is %s",3448 __FUNCTION__, StateAsCString(state));3449 } else {3450 LLDB_LOGF(log, "Target::%s the process instance doesn't currently exist.",3451 __FUNCTION__);3452 }3453 }3454 3455 launch_info.GetFlags().Set(eLaunchFlagDebug);3456 3457 SaveScriptedLaunchInfo(launch_info);3458 3459 // Get the value of synchronous execution here. If you wait till after you3460 // have started to run, then you could have hit a breakpoint, whose command3461 // might switch the value, and then you'll pick up that incorrect value.3462 Debugger &debugger = GetDebugger();3463 const bool synchronous_execution =3464 debugger.GetCommandInterpreter().GetSynchronous();3465 3466 PlatformSP platform_sp(GetPlatform());3467 3468 FinalizeFileActions(launch_info);3469 3470 if (state == eStateConnected) {3471 if (launch_info.GetFlags().Test(eLaunchFlagLaunchInTTY))3472 return Status::FromErrorString(3473 "can't launch in tty when launching through a remote connection");3474 }3475 3476 if (!launch_info.GetArchitecture().IsValid())3477 launch_info.GetArchitecture() = GetArchitecture();3478 3479 // Hijacking events of the process to be created to be sure that all events3480 // until the first stop are intercepted (in case if platform doesn't define3481 // its own hijacking listener or if the process is created by the target3482 // manually, without the platform).3483 if (!launch_info.GetHijackListener())3484 launch_info.SetHijackListener(Listener::MakeListener(3485 Process::LaunchSynchronousHijackListenerName.data()));3486 3487 // If we're not already connected to the process, and if we have a platform3488 // that can launch a process for debugging, go ahead and do that here.3489 if (state != eStateConnected && platform_sp &&3490 platform_sp->CanDebugProcess() && !launch_info.IsScriptedProcess()) {3491 LLDB_LOGF(log, "Target::%s asking the platform to debug the process",3492 __FUNCTION__);3493 3494 // If there was a previous process, delete it before we make the new one.3495 // One subtle point, we delete the process before we release the reference3496 // to m_process_sp. That way even if we are the last owner, the process3497 // will get Finalized before it gets destroyed.3498 DeleteCurrentProcess();3499 3500 m_process_sp =3501 GetPlatform()->DebugProcess(launch_info, debugger, *this, error);3502 3503 } else {3504 LLDB_LOGF(log,3505 "Target::%s the platform doesn't know how to debug a "3506 "process, getting a process plugin to do this for us.",3507 __FUNCTION__);3508 3509 if (state == eStateConnected) {3510 assert(m_process_sp);3511 } else {3512 // Use a Process plugin to construct the process.3513 CreateProcess(launch_info.GetListener(),3514 launch_info.GetProcessPluginName(), nullptr, false);3515 }3516 3517 // Since we didn't have a platform launch the process, launch it here.3518 if (m_process_sp) {3519 m_process_sp->HijackProcessEvents(launch_info.GetHijackListener());3520 m_process_sp->SetShadowListener(launch_info.GetShadowListener());3521 error = m_process_sp->Launch(launch_info);3522 }3523 }3524 3525 if (!error.Success())3526 return error;3527 3528 if (!m_process_sp)3529 return Status::FromErrorString("failed to launch or debug process");3530 3531 bool rebroadcast_first_stop =3532 !synchronous_execution &&3533 launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);3534 3535 assert(launch_info.GetHijackListener());3536 3537 EventSP first_stop_event_sp;3538 state = m_process_sp->WaitForProcessToStop(std::nullopt, &first_stop_event_sp,3539 rebroadcast_first_stop,3540 launch_info.GetHijackListener());3541 m_process_sp->RestoreProcessEvents();3542 3543 if (rebroadcast_first_stop) {3544 // We don't need to run the stop hooks by hand here, they will get3545 // triggered when this rebroadcast event gets fetched.3546 assert(first_stop_event_sp);3547 m_process_sp->BroadcastEvent(first_stop_event_sp);3548 return error;3549 }3550 // Run the stop hooks that want to run at entry.3551 RunStopHooks(true /* at entry point */);3552 3553 switch (state) {3554 case eStateStopped: {3555 if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))3556 break;3557 if (synchronous_execution)3558 // Now we have handled the stop-from-attach, and we are just3559 // switching to a synchronous resume. So we should switch to the3560 // SyncResume hijacker.3561 m_process_sp->ResumeSynchronous(stream);3562 else3563 error = m_process_sp->Resume();3564 if (!error.Success()) {3565 error = Status::FromErrorStringWithFormat(3566 "process resume at entry point failed: %s", error.AsCString());3567 }3568 } break;3569 case eStateExited: {3570 bool with_shell = !!launch_info.GetShell();3571 const int exit_status = m_process_sp->GetExitStatus();3572 const char *exit_desc = m_process_sp->GetExitDescription();3573 std::string desc;3574 if (exit_desc && exit_desc[0])3575 desc = " (" + std::string(exit_desc) + ')';3576 if (with_shell)3577 error = Status::FromErrorStringWithFormat(3578 "process exited with status %i%s\n"3579 "'r' and 'run' are aliases that default to launching through a "3580 "shell.\n"3581 "Try launching without going through a shell by using "3582 "'process launch'.",3583 exit_status, desc.c_str());3584 else3585 error = Status::FromErrorStringWithFormat(3586 "process exited with status %i%s", exit_status, desc.c_str());3587 } break;3588 default:3589 error = Status::FromErrorStringWithFormat(3590 "initial process state wasn't stopped: %s", StateAsCString(state));3591 break;3592 }3593 return error;3594}3595 3596void Target::SetTrace(const TraceSP &trace_sp) { m_trace_sp = trace_sp; }3597 3598TraceSP Target::GetTrace() { return m_trace_sp; }3599 3600llvm::Expected<TraceSP> Target::CreateTrace() {3601 if (!m_process_sp)3602 return llvm::createStringError(llvm::inconvertibleErrorCode(),3603 "A process is required for tracing");3604 if (m_trace_sp)3605 return llvm::createStringError(llvm::inconvertibleErrorCode(),3606 "A trace already exists for the target");3607 3608 llvm::Expected<TraceSupportedResponse> trace_type =3609 m_process_sp->TraceSupported();3610 if (!trace_type)3611 return llvm::createStringError(3612 llvm::inconvertibleErrorCode(), "Tracing is not supported. %s",3613 llvm::toString(trace_type.takeError()).c_str());3614 if (llvm::Expected<TraceSP> trace_sp =3615 Trace::FindPluginForLiveProcess(trace_type->name, *m_process_sp))3616 m_trace_sp = *trace_sp;3617 else3618 return llvm::createStringError(3619 llvm::inconvertibleErrorCode(),3620 "Couldn't create a Trace object for the process. %s",3621 llvm::toString(trace_sp.takeError()).c_str());3622 return m_trace_sp;3623}3624 3625llvm::Expected<TraceSP> Target::GetTraceOrCreate() {3626 if (m_trace_sp)3627 return m_trace_sp;3628 return CreateTrace();3629}3630 3631Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) {3632 Progress attach_progress("Waiting to attach to process");3633 m_stats.SetLaunchOrAttachTime();3634 auto state = eStateInvalid;3635 auto process_sp = GetProcessSP();3636 if (process_sp) {3637 state = process_sp->GetState();3638 if (process_sp->IsAlive() && state != eStateConnected) {3639 if (state == eStateAttaching)3640 return Status::FromErrorString("process attach is in progress");3641 return Status::FromErrorString("a process is already being debugged");3642 }3643 }3644 3645 const ModuleSP old_exec_module_sp = GetExecutableModule();3646 3647 // If no process info was specified, then use the target executable name as3648 // the process to attach to by default3649 if (!attach_info.ProcessInfoSpecified()) {3650 if (old_exec_module_sp)3651 attach_info.GetExecutableFile().SetFilename(3652 old_exec_module_sp->GetPlatformFileSpec().GetFilename());3653 3654 if (!attach_info.ProcessInfoSpecified()) {3655 return Status::FromErrorString(3656 "no process specified, create a target with a file, or "3657 "specify the --pid or --name");3658 }3659 }3660 3661 const auto platform_sp =3662 GetDebugger().GetPlatformList().GetSelectedPlatform();3663 ListenerSP hijack_listener_sp;3664 const bool async = attach_info.GetAsync();3665 if (!async) {3666 hijack_listener_sp = Listener::MakeListener(3667 Process::AttachSynchronousHijackListenerName.data());3668 attach_info.SetHijackListener(hijack_listener_sp);3669 }3670 3671 Status error;3672 if (state != eStateConnected && platform_sp != nullptr &&3673 platform_sp->CanDebugProcess() && !attach_info.IsScriptedProcess()) {3674 SetPlatform(platform_sp);3675 process_sp = platform_sp->Attach(attach_info, GetDebugger(), this, error);3676 } else {3677 if (state != eStateConnected) {3678 SaveScriptedLaunchInfo(attach_info);3679 llvm::StringRef plugin_name = attach_info.GetProcessPluginName();3680 process_sp =3681 CreateProcess(attach_info.GetListenerForProcess(GetDebugger()),3682 plugin_name, nullptr, false);3683 if (!process_sp) {3684 error = Status::FromErrorStringWithFormatv(3685 "failed to create process using plugin '{0}'",3686 plugin_name.empty() ? "<empty>" : plugin_name);3687 return error;3688 }3689 }3690 if (hijack_listener_sp)3691 process_sp->HijackProcessEvents(hijack_listener_sp);3692 error = process_sp->Attach(attach_info);3693 }3694 3695 if (error.Success() && process_sp) {3696 if (async) {3697 process_sp->RestoreProcessEvents();3698 } else {3699 // We are stopping all the way out to the user, so update selected frames.3700 state = process_sp->WaitForProcessToStop(3701 std::nullopt, nullptr, false, attach_info.GetHijackListener(), stream,3702 true, SelectMostRelevantFrame);3703 process_sp->RestoreProcessEvents();3704 3705 // Run the stop hooks here. Since we were hijacking the events, they3706 // wouldn't have gotten run as part of event delivery.3707 RunStopHooks(/* at_initial_stop= */ true);3708 3709 if (state != eStateStopped) {3710 const char *exit_desc = process_sp->GetExitDescription();3711 if (exit_desc)3712 error = Status::FromErrorStringWithFormat("%s", exit_desc);3713 else3714 error = Status::FromErrorString(3715 "process did not stop (no such process or permission problem?)");3716 process_sp->Destroy(false);3717 }3718 }3719 }3720 return error;3721}3722 3723void Target::FinalizeFileActions(ProcessLaunchInfo &info) {3724 Log *log = GetLog(LLDBLog::Process);3725 3726 // Finalize the file actions, and if none were given, default to opening up a3727 // pseudo terminal3728 PlatformSP platform_sp = GetPlatform();3729 const bool default_to_use_pty =3730 m_platform_sp ? m_platform_sp->IsHost() : false;3731 LLDB_LOG(3732 log,3733 "have platform={0}, platform_sp->IsHost()={1}, default_to_use_pty={2}",3734 bool(platform_sp),3735 platform_sp ? (platform_sp->IsHost() ? "true" : "false") : "n/a",3736 default_to_use_pty);3737 3738 // If nothing for stdin or stdout or stderr was specified, then check the3739 // process for any default settings that were set with "settings set"3740 if (info.GetFileActionForFD(STDIN_FILENO) == nullptr ||3741 info.GetFileActionForFD(STDOUT_FILENO) == nullptr ||3742 info.GetFileActionForFD(STDERR_FILENO) == nullptr) {3743 LLDB_LOG(log, "at least one of stdin/stdout/stderr was not set, evaluating "3744 "default handling");3745 3746 if (info.GetFlags().Test(eLaunchFlagLaunchInTTY)) {3747 // Do nothing, if we are launching in a remote terminal no file actions3748 // should be done at all.3749 return;3750 }3751 3752 if (info.GetFlags().Test(eLaunchFlagDisableSTDIO)) {3753 LLDB_LOG(log, "eLaunchFlagDisableSTDIO set, adding suppression action "3754 "for stdin, stdout and stderr");3755 info.AppendSuppressFileAction(STDIN_FILENO, true, false);3756 info.AppendSuppressFileAction(STDOUT_FILENO, false, true);3757 info.AppendSuppressFileAction(STDERR_FILENO, false, true);3758 } else {3759 // Check for any values that might have gotten set with any of: (lldb)3760 // settings set target.input-path (lldb) settings set target.output-path3761 // (lldb) settings set target.error-path3762 FileSpec in_file_spec;3763 FileSpec out_file_spec;3764 FileSpec err_file_spec;3765 // Only override with the target settings if we don't already have an3766 // action for in, out or error3767 if (info.GetFileActionForFD(STDIN_FILENO) == nullptr)3768 in_file_spec = GetStandardInputPath();3769 if (info.GetFileActionForFD(STDOUT_FILENO) == nullptr)3770 out_file_spec = GetStandardOutputPath();3771 if (info.GetFileActionForFD(STDERR_FILENO) == nullptr)3772 err_file_spec = GetStandardErrorPath();3773 3774 LLDB_LOG(log, "target stdin='{0}', target stdout='{1}', stderr='{2}'",3775 in_file_spec, out_file_spec, err_file_spec);3776 3777 if (in_file_spec) {3778 info.AppendOpenFileAction(STDIN_FILENO, in_file_spec, true, false);3779 LLDB_LOG(log, "appended stdin open file action for {0}", in_file_spec);3780 }3781 3782 if (out_file_spec) {3783 info.AppendOpenFileAction(STDOUT_FILENO, out_file_spec, false, true);3784 LLDB_LOG(log, "appended stdout open file action for {0}",3785 out_file_spec);3786 }3787 3788 if (err_file_spec) {3789 info.AppendOpenFileAction(STDERR_FILENO, err_file_spec, false, true);3790 LLDB_LOG(log, "appended stderr open file action for {0}",3791 err_file_spec);3792 }3793 3794 if (default_to_use_pty) {3795 llvm::Error Err = info.SetUpPtyRedirection();3796 LLDB_LOG_ERROR(log, std::move(Err), "SetUpPtyRedirection failed: {0}");3797 }3798 }3799 }3800}3801 3802void Target::AddDummySignal(llvm::StringRef name, LazyBool pass, LazyBool notify,3803 LazyBool stop) {3804 if (name.empty())3805 return;3806 // Don't add a signal if all the actions are trivial:3807 if (pass == eLazyBoolCalculate && notify == eLazyBoolCalculate3808 && stop == eLazyBoolCalculate)3809 return;3810 3811 auto& elem = m_dummy_signals[name];3812 elem.pass = pass;3813 elem.notify = notify;3814 elem.stop = stop;3815}3816 3817bool Target::UpdateSignalFromDummy(UnixSignalsSP signals_sp,3818 const DummySignalElement &elem) {3819 if (!signals_sp)3820 return false;3821 3822 int32_t signo3823 = signals_sp->GetSignalNumberFromName(elem.first().str().c_str());3824 if (signo == LLDB_INVALID_SIGNAL_NUMBER)3825 return false;3826 3827 if (elem.second.pass == eLazyBoolYes)3828 signals_sp->SetShouldSuppress(signo, false);3829 else if (elem.second.pass == eLazyBoolNo)3830 signals_sp->SetShouldSuppress(signo, true);3831 3832 if (elem.second.notify == eLazyBoolYes)3833 signals_sp->SetShouldNotify(signo, true);3834 else if (elem.second.notify == eLazyBoolNo)3835 signals_sp->SetShouldNotify(signo, false);3836 3837 if (elem.second.stop == eLazyBoolYes)3838 signals_sp->SetShouldStop(signo, true);3839 else if (elem.second.stop == eLazyBoolNo)3840 signals_sp->SetShouldStop(signo, false);3841 return true;3842}3843 3844bool Target::ResetSignalFromDummy(UnixSignalsSP signals_sp,3845 const DummySignalElement &elem) {3846 if (!signals_sp)3847 return false;3848 int32_t signo3849 = signals_sp->GetSignalNumberFromName(elem.first().str().c_str());3850 if (signo == LLDB_INVALID_SIGNAL_NUMBER)3851 return false;3852 bool do_pass = elem.second.pass != eLazyBoolCalculate;3853 bool do_stop = elem.second.stop != eLazyBoolCalculate;3854 bool do_notify = elem.second.notify != eLazyBoolCalculate;3855 signals_sp->ResetSignal(signo, do_stop, do_notify, do_pass);3856 return true;3857}3858 3859void Target::UpdateSignalsFromDummy(UnixSignalsSP signals_sp,3860 StreamSP warning_stream_sp) {3861 if (!signals_sp)3862 return;3863 3864 for (const auto &elem : m_dummy_signals) {3865 if (!UpdateSignalFromDummy(signals_sp, elem))3866 warning_stream_sp->Printf("Target signal '%s' not found in process\n",3867 elem.first().str().c_str());3868 }3869}3870 3871void Target::ClearDummySignals(Args &signal_names) {3872 ProcessSP process_sp = GetProcessSP();3873 // The simplest case, delete them all with no process to update.3874 if (signal_names.GetArgumentCount() == 0 && !process_sp) {3875 m_dummy_signals.clear();3876 return;3877 }3878 UnixSignalsSP signals_sp;3879 if (process_sp)3880 signals_sp = process_sp->GetUnixSignals();3881 3882 for (const Args::ArgEntry &entry : signal_names) {3883 const char *signal_name = entry.c_str();3884 auto elem = m_dummy_signals.find(signal_name);3885 // If we didn't find it go on.3886 // FIXME: Should I pipe error handling through here?3887 if (elem == m_dummy_signals.end()) {3888 continue;3889 }3890 if (signals_sp)3891 ResetSignalFromDummy(signals_sp, *elem);3892 m_dummy_signals.erase(elem);3893 }3894}3895 3896void Target::PrintDummySignals(Stream &strm, Args &signal_args) {3897 strm.Printf("NAME PASS STOP NOTIFY\n");3898 strm.Printf("=========== ======= ======= =======\n");3899 3900 auto str_for_lazy = [] (LazyBool lazy) -> const char * {3901 switch (lazy) {3902 case eLazyBoolCalculate: return "not set";3903 case eLazyBoolYes: return "true ";3904 case eLazyBoolNo: return "false ";3905 }3906 llvm_unreachable("Fully covered switch above!");3907 };3908 size_t num_args = signal_args.GetArgumentCount();3909 for (const auto &elem : m_dummy_signals) {3910 bool print_it = false;3911 for (size_t idx = 0; idx < num_args; idx++) {3912 if (elem.first() == signal_args.GetArgumentAtIndex(idx)) {3913 print_it = true;3914 break;3915 }3916 }3917 if (print_it) {3918 strm.Printf("%-11s ", elem.first().str().c_str());3919 strm.Printf("%s %s %s\n", str_for_lazy(elem.second.pass),3920 str_for_lazy(elem.second.stop),3921 str_for_lazy(elem.second.notify));3922 }3923 }3924}3925 3926// Target::StopHook3927Target::StopHook::StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid)3928 : UserID(uid), m_target_sp(target_sp), m_specifier_sp(),3929 m_thread_spec_up() {}3930 3931Target::StopHook::StopHook(const StopHook &rhs)3932 : UserID(rhs.GetID()), m_target_sp(rhs.m_target_sp),3933 m_specifier_sp(rhs.m_specifier_sp), m_thread_spec_up(),3934 m_active(rhs.m_active), m_auto_continue(rhs.m_auto_continue) {3935 if (rhs.m_thread_spec_up)3936 m_thread_spec_up = std::make_unique<ThreadSpec>(*rhs.m_thread_spec_up);3937}3938 3939void Target::StopHook::SetSpecifier(SymbolContextSpecifier *specifier) {3940 m_specifier_sp.reset(specifier);3941}3942 3943void Target::StopHook::SetThreadSpecifier(ThreadSpec *specifier) {3944 m_thread_spec_up.reset(specifier);3945}3946 3947bool Target::StopHook::ExecutionContextPasses(const ExecutionContext &exc_ctx) {3948 SymbolContextSpecifier *specifier = GetSpecifier();3949 if (!specifier)3950 return true;3951 3952 bool will_run = true;3953 if (exc_ctx.GetFramePtr())3954 will_run = GetSpecifier()->SymbolContextMatches(3955 exc_ctx.GetFramePtr()->GetSymbolContext(eSymbolContextEverything));3956 if (will_run && GetThreadSpecifier() != nullptr)3957 will_run =3958 GetThreadSpecifier()->ThreadPassesBasicTests(exc_ctx.GetThreadRef());3959 3960 return will_run;3961}3962 3963void Target::StopHook::GetDescription(Stream &s,3964 lldb::DescriptionLevel level) const {3965 3966 // For brief descriptions, only print the subclass description:3967 if (level == eDescriptionLevelBrief) {3968 GetSubclassDescription(s, level);3969 return;3970 }3971 3972 auto indent_scope = s.MakeIndentScope();3973 3974 s.Printf("Hook: %" PRIu64 "\n", GetID());3975 if (m_active)3976 s.Indent("State: enabled\n");3977 else3978 s.Indent("State: disabled\n");3979 3980 if (m_auto_continue)3981 s.Indent("AutoContinue on\n");3982 3983 if (m_specifier_sp) {3984 s.Indent();3985 s.PutCString("Specifier:\n");3986 auto indent_scope = s.MakeIndentScope();3987 m_specifier_sp->GetDescription(&s, level);3988 }3989 3990 if (m_thread_spec_up) {3991 StreamString tmp;3992 s.Indent("Thread:\n");3993 m_thread_spec_up->GetDescription(&tmp, level);3994 auto indent_scope = s.MakeIndentScope();3995 s.Indent(tmp.GetString());3996 s.PutCString("\n");3997 }3998 GetSubclassDescription(s, level);3999}4000 4001void Target::StopHookCommandLine::GetSubclassDescription(4002 Stream &s, lldb::DescriptionLevel level) const {4003 // The brief description just prints the first command.4004 if (level == eDescriptionLevelBrief) {4005 if (m_commands.GetSize() == 1)4006 s.PutCString(m_commands.GetStringAtIndex(0));4007 return;4008 }4009 s.Indent("Commands:\n");4010 auto indent_scope = s.MakeIndentScope(4);4011 uint32_t num_commands = m_commands.GetSize();4012 for (uint32_t i = 0; i < num_commands; i++) {4013 s.Indent(m_commands.GetStringAtIndex(i));4014 s.PutCString("\n");4015 }4016}4017 4018// Target::StopHookCommandLine4019void Target::StopHookCommandLine::SetActionFromString(const std::string &string) {4020 GetCommands().SplitIntoLines(string);4021}4022 4023void Target::StopHookCommandLine::SetActionFromStrings(4024 const std::vector<std::string> &strings) {4025 for (auto string : strings)4026 GetCommands().AppendString(string.c_str());4027}4028 4029Target::StopHook::StopHookResult4030Target::StopHookCommandLine::HandleStop(ExecutionContext &exc_ctx,4031 StreamSP output_sp) {4032 assert(exc_ctx.GetTargetPtr() && "Can't call PerformAction on a context "4033 "with no target");4034 4035 if (!m_commands.GetSize())4036 return StopHookResult::KeepStopped;4037 4038 CommandReturnObject result(false);4039 result.SetImmediateOutputStream(output_sp);4040 result.SetInteractive(false);4041 Debugger &debugger = exc_ctx.GetTargetPtr()->GetDebugger();4042 CommandInterpreterRunOptions options;4043 options.SetStopOnContinue(true);4044 options.SetStopOnError(true);4045 options.SetEchoCommands(false);4046 options.SetPrintResults(true);4047 options.SetPrintErrors(true);4048 options.SetAddToHistory(false);4049 4050 // Force Async:4051 bool old_async = debugger.GetAsyncExecution();4052 debugger.SetAsyncExecution(true);4053 debugger.GetCommandInterpreter().HandleCommands(GetCommands(), exc_ctx,4054 options, result);4055 debugger.SetAsyncExecution(old_async);4056 lldb::ReturnStatus status = result.GetStatus();4057 if (status == eReturnStatusSuccessContinuingNoResult ||4058 status == eReturnStatusSuccessContinuingResult)4059 return StopHookResult::AlreadyContinued;4060 return StopHookResult::KeepStopped;4061}4062 4063// Target::StopHookScripted4064Status Target::StopHookScripted::SetScriptCallback(4065 std::string class_name, StructuredData::ObjectSP extra_args_sp) {4066 Status error;4067 4068 ScriptInterpreter *script_interp =4069 GetTarget()->GetDebugger().GetScriptInterpreter();4070 if (!script_interp) {4071 error = Status::FromErrorString("No script interpreter installed.");4072 return error;4073 }4074 4075 m_interface_sp = script_interp->CreateScriptedStopHookInterface();4076 if (!m_interface_sp) {4077 error = Status::FromErrorStringWithFormat(4078 "ScriptedStopHook::%s () - ERROR: %s", __FUNCTION__,4079 "Script interpreter couldn't create Scripted Stop Hook Interface");4080 return error;4081 }4082 4083 m_class_name = class_name;4084 m_extra_args.SetObjectSP(extra_args_sp);4085 4086 auto obj_or_err = m_interface_sp->CreatePluginObject(4087 m_class_name, GetTarget(), m_extra_args);4088 if (!obj_or_err) {4089 return Status::FromError(obj_or_err.takeError());4090 }4091 4092 StructuredData::ObjectSP object_sp = *obj_or_err;4093 if (!object_sp || !object_sp->IsValid()) {4094 error = Status::FromErrorStringWithFormat(4095 "ScriptedStopHook::%s () - ERROR: %s", __FUNCTION__,4096 "Failed to create valid script object");4097 return error;4098 }4099 4100 return {};4101}4102 4103Target::StopHook::StopHookResult4104Target::StopHookScripted::HandleStop(ExecutionContext &exc_ctx,4105 StreamSP output_sp) {4106 assert(exc_ctx.GetTargetPtr() && "Can't call HandleStop on a context "4107 "with no target");4108 4109 if (!m_interface_sp)4110 return StopHookResult::KeepStopped;4111 4112 lldb::StreamSP stream = std::make_shared<lldb_private::StreamString>();4113 auto should_stop_or_err = m_interface_sp->HandleStop(exc_ctx, stream);4114 output_sp->PutCString(4115 reinterpret_cast<StreamString *>(stream.get())->GetData());4116 if (!should_stop_or_err)4117 return StopHookResult::KeepStopped;4118 4119 return *should_stop_or_err ? StopHookResult::KeepStopped4120 : StopHookResult::RequestContinue;4121}4122 4123void Target::StopHookScripted::GetSubclassDescription(4124 Stream &s, lldb::DescriptionLevel level) const {4125 if (level == eDescriptionLevelBrief) {4126 s.PutCString(m_class_name);4127 return;4128 }4129 s.Indent("Class:");4130 s.Printf("%s\n", m_class_name.c_str());4131 4132 // Now print the extra args:4133 // FIXME: We should use StructuredData.GetDescription on the m_extra_args4134 // but that seems to rely on some printing plugin that doesn't exist.4135 if (!m_extra_args.IsValid())4136 return;4137 StructuredData::ObjectSP object_sp = m_extra_args.GetObjectSP();4138 if (!object_sp || !object_sp->IsValid())4139 return;4140 4141 StructuredData::Dictionary *as_dict = object_sp->GetAsDictionary();4142 if (!as_dict || !as_dict->IsValid())4143 return;4144 4145 uint32_t num_keys = as_dict->GetSize();4146 if (num_keys == 0)4147 return;4148 4149 s.Indent("Args:\n");4150 auto indent_scope = s.MakeIndentScope(4);4151 4152 auto print_one_element = [&s](llvm::StringRef key,4153 StructuredData::Object *object) {4154 s.Indent();4155 s.Format("{0} : {1}\n", key, object->GetStringValue());4156 return true;4157 };4158 4159 as_dict->ForEach(print_one_element);4160}4161 4162static constexpr OptionEnumValueElement g_dynamic_value_types[] = {4163 {4164 eNoDynamicValues,4165 "no-dynamic-values",4166 "Don't calculate the dynamic type of values",4167 },4168 {4169 eDynamicCanRunTarget,4170 "run-target",4171 "Calculate the dynamic type of values "4172 "even if you have to run the target.",4173 },4174 {4175 eDynamicDontRunTarget,4176 "no-run-target",4177 "Calculate the dynamic type of values, but don't run the target.",4178 },4179};4180 4181OptionEnumValues lldb_private::GetDynamicValueTypes() {4182 return OptionEnumValues(g_dynamic_value_types);4183}4184 4185static constexpr OptionEnumValueElement g_inline_breakpoint_enums[] = {4186 {4187 eInlineBreakpointsNever,4188 "never",4189 "Never look for inline breakpoint locations (fastest). This setting "4190 "should only be used if you know that no inlining occurs in your"4191 "programs.",4192 },4193 {4194 eInlineBreakpointsHeaders,4195 "headers",4196 "Only check for inline breakpoint locations when setting breakpoints "4197 "in header files, but not when setting breakpoint in implementation "4198 "source files (default).",4199 },4200 {4201 eInlineBreakpointsAlways,4202 "always",4203 "Always look for inline breakpoint locations when setting file and "4204 "line breakpoints (slower but most accurate).",4205 },4206};4207 4208enum x86DisassemblyFlavor {4209 eX86DisFlavorDefault,4210 eX86DisFlavorIntel,4211 eX86DisFlavorATT4212};4213 4214static constexpr OptionEnumValueElement g_x86_dis_flavor_value_types[] = {4215 {4216 eX86DisFlavorDefault,4217 "default",4218 "Disassembler default (currently att).",4219 },4220 {4221 eX86DisFlavorIntel,4222 "intel",4223 "Intel disassembler flavor.",4224 },4225 {4226 eX86DisFlavorATT,4227 "att",4228 "AT&T disassembler flavor.",4229 },4230};4231 4232static constexpr OptionEnumValueElement g_import_std_module_value_types[] = {4233 {4234 eImportStdModuleFalse,4235 "false",4236 "Never import the 'std' C++ module in the expression parser.",4237 },4238 {4239 eImportStdModuleFallback,4240 "fallback",4241 "Retry evaluating expressions with an imported 'std' C++ module if they"4242 " failed to parse without the module. This allows evaluating more "4243 "complex expressions involving C++ standard library types."4244 },4245 {4246 eImportStdModuleTrue,4247 "true",4248 "Always import the 'std' C++ module. This allows evaluating more "4249 "complex expressions involving C++ standard library types. This feature"4250 " is experimental."4251 },4252};4253 4254static constexpr OptionEnumValueElement4255 g_dynamic_class_info_helper_value_types[] = {4256 {4257 eDynamicClassInfoHelperAuto,4258 "auto",4259 "Automatically determine the most appropriate method for the "4260 "target OS.",4261 },4262 {eDynamicClassInfoHelperRealizedClassesStruct, "RealizedClassesStruct",4263 "Prefer using the realized classes struct."},4264 {eDynamicClassInfoHelperCopyRealizedClassList, "CopyRealizedClassList",4265 "Prefer using the CopyRealizedClassList API."},4266 {eDynamicClassInfoHelperGetRealizedClassList, "GetRealizedClassList",4267 "Prefer using the GetRealizedClassList API."},4268};4269 4270static constexpr OptionEnumValueElement g_hex_immediate_style_values[] = {4271 {4272 Disassembler::eHexStyleC,4273 "c",4274 "C-style (0xffff).",4275 },4276 {4277 Disassembler::eHexStyleAsm,4278 "asm",4279 "Asm-style (0ffffh).",4280 },4281};4282 4283static constexpr OptionEnumValueElement g_load_script_from_sym_file_values[] = {4284 {4285 eLoadScriptFromSymFileTrue,4286 "true",4287 "Load debug scripts inside symbol files",4288 },4289 {4290 eLoadScriptFromSymFileFalse,4291 "false",4292 "Do not load debug scripts inside symbol files.",4293 },4294 {4295 eLoadScriptFromSymFileWarn,4296 "warn",4297 "Warn about debug scripts inside symbol files but do not load them.",4298 },4299};4300 4301static constexpr OptionEnumValueElement g_load_cwd_lldbinit_values[] = {4302 {4303 eLoadCWDlldbinitTrue,4304 "true",4305 "Load .lldbinit files from current directory",4306 },4307 {4308 eLoadCWDlldbinitFalse,4309 "false",4310 "Do not load .lldbinit files from current directory",4311 },4312 {4313 eLoadCWDlldbinitWarn,4314 "warn",4315 "Warn about loading .lldbinit files from current directory",4316 },4317};4318 4319static constexpr OptionEnumValueElement g_memory_module_load_level_values[] = {4320 {4321 eMemoryModuleLoadLevelMinimal,4322 "minimal",4323 "Load minimal information when loading modules from memory. Currently "4324 "this setting loads sections only.",4325 },4326 {4327 eMemoryModuleLoadLevelPartial,4328 "partial",4329 "Load partial information when loading modules from memory. Currently "4330 "this setting loads sections and function bounds.",4331 },4332 {4333 eMemoryModuleLoadLevelComplete,4334 "complete",4335 "Load complete information when loading modules from memory. Currently "4336 "this setting loads sections and all symbols.",4337 },4338};4339 4340#define LLDB_PROPERTIES_target4341#include "TargetProperties.inc"4342 4343enum {4344#define LLDB_PROPERTIES_target4345#include "TargetPropertiesEnum.inc"4346 ePropertyExperimental,4347};4348 4349class TargetOptionValueProperties4350 : public Cloneable<TargetOptionValueProperties, OptionValueProperties> {4351public:4352 TargetOptionValueProperties(llvm::StringRef name) : Cloneable(name) {}4353 4354 const Property *4355 GetPropertyAtIndex(size_t idx,4356 const ExecutionContext *exe_ctx = nullptr) const override {4357 // When getting the value for a key from the target options, we will always4358 // try and grab the setting from the current target if there is one. Else4359 // we just use the one from this instance.4360 if (exe_ctx) {4361 Target *target = exe_ctx->GetTargetPtr();4362 if (target) {4363 TargetOptionValueProperties *target_properties =4364 static_cast<TargetOptionValueProperties *>(4365 target->GetValueProperties().get());4366 if (this != target_properties)4367 return target_properties->ProtectedGetPropertyAtIndex(idx);4368 }4369 }4370 return ProtectedGetPropertyAtIndex(idx);4371 }4372};4373 4374// TargetProperties4375#define LLDB_PROPERTIES_target_experimental4376#include "TargetProperties.inc"4377 4378enum {4379#define LLDB_PROPERTIES_target_experimental4380#include "TargetPropertiesEnum.inc"4381};4382 4383class TargetExperimentalOptionValueProperties4384 : public Cloneable<TargetExperimentalOptionValueProperties,4385 OptionValueProperties> {4386public:4387 TargetExperimentalOptionValueProperties()4388 : Cloneable(Properties::GetExperimentalSettingsName()) {}4389};4390 4391TargetExperimentalProperties::TargetExperimentalProperties()4392 : Properties(OptionValuePropertiesSP(4393 new TargetExperimentalOptionValueProperties())) {4394 m_collection_sp->Initialize(g_target_experimental_properties);4395}4396 4397// TargetProperties4398TargetProperties::TargetProperties(Target *target)4399 : Properties(), m_launch_info(), m_target(target) {4400 if (target) {4401 m_collection_sp =4402 OptionValueProperties::CreateLocalCopy(Target::GetGlobalProperties());4403 4404 // Set callbacks to update launch_info whenever "settins set" updated any4405 // of these properties4406 m_collection_sp->SetValueChangedCallback(4407 ePropertyArg0, [this] { Arg0ValueChangedCallback(); });4408 m_collection_sp->SetValueChangedCallback(4409 ePropertyRunArgs, [this] { RunArgsValueChangedCallback(); });4410 m_collection_sp->SetValueChangedCallback(4411 ePropertyEnvVars, [this] { EnvVarsValueChangedCallback(); });4412 m_collection_sp->SetValueChangedCallback(4413 ePropertyUnsetEnvVars, [this] { EnvVarsValueChangedCallback(); });4414 m_collection_sp->SetValueChangedCallback(4415 ePropertyInheritEnv, [this] { EnvVarsValueChangedCallback(); });4416 m_collection_sp->SetValueChangedCallback(4417 ePropertyInputPath, [this] { InputPathValueChangedCallback(); });4418 m_collection_sp->SetValueChangedCallback(4419 ePropertyOutputPath, [this] { OutputPathValueChangedCallback(); });4420 m_collection_sp->SetValueChangedCallback(4421 ePropertyErrorPath, [this] { ErrorPathValueChangedCallback(); });4422 m_collection_sp->SetValueChangedCallback(ePropertyDetachOnError, [this] {4423 DetachOnErrorValueChangedCallback();4424 });4425 m_collection_sp->SetValueChangedCallback(4426 ePropertyDisableASLR, [this] { DisableASLRValueChangedCallback(); });4427 m_collection_sp->SetValueChangedCallback(4428 ePropertyInheritTCC, [this] { InheritTCCValueChangedCallback(); });4429 m_collection_sp->SetValueChangedCallback(4430 ePropertyDisableSTDIO, [this] { DisableSTDIOValueChangedCallback(); });4431 4432 m_collection_sp->SetValueChangedCallback(4433 ePropertySaveObjectsDir, [this] { CheckJITObjectsDir(); });4434 m_experimental_properties_up =4435 std::make_unique<TargetExperimentalProperties>();4436 m_collection_sp->AppendProperty(4437 Properties::GetExperimentalSettingsName(),4438 "Experimental settings - setting these won't produce "4439 "errors if the setting is not present.",4440 true, m_experimental_properties_up->GetValueProperties());4441 } else {4442 m_collection_sp = std::make_shared<TargetOptionValueProperties>("target");4443 m_collection_sp->Initialize(g_target_properties);4444 m_experimental_properties_up =4445 std::make_unique<TargetExperimentalProperties>();4446 m_collection_sp->AppendProperty(4447 Properties::GetExperimentalSettingsName(),4448 "Experimental settings - setting these won't produce "4449 "errors if the setting is not present.",4450 true, m_experimental_properties_up->GetValueProperties());4451 m_collection_sp->AppendProperty(4452 "process", "Settings specific to processes.", true,4453 Process::GetGlobalProperties().GetValueProperties());4454 m_collection_sp->SetValueChangedCallback(4455 ePropertySaveObjectsDir, [this] { CheckJITObjectsDir(); });4456 }4457}4458 4459TargetProperties::~TargetProperties() = default;4460 4461void TargetProperties::UpdateLaunchInfoFromProperties() {4462 Arg0ValueChangedCallback();4463 RunArgsValueChangedCallback();4464 EnvVarsValueChangedCallback();4465 InputPathValueChangedCallback();4466 OutputPathValueChangedCallback();4467 ErrorPathValueChangedCallback();4468 DetachOnErrorValueChangedCallback();4469 DisableASLRValueChangedCallback();4470 InheritTCCValueChangedCallback();4471 DisableSTDIOValueChangedCallback();4472}4473 4474std::optional<bool> TargetProperties::GetExperimentalPropertyValue(4475 size_t prop_idx, ExecutionContext *exe_ctx) const {4476 const Property *exp_property =4477 m_collection_sp->GetPropertyAtIndex(ePropertyExperimental, exe_ctx);4478 OptionValueProperties *exp_values =4479 exp_property->GetValue()->GetAsProperties();4480 if (exp_values)4481 return exp_values->GetPropertyAtIndexAs<bool>(prop_idx, exe_ctx);4482 return std::nullopt;4483}4484 4485bool TargetProperties::GetInjectLocalVariables(4486 ExecutionContext *exe_ctx) const {4487 return GetExperimentalPropertyValue(ePropertyInjectLocalVars, exe_ctx)4488 .value_or(true);4489}4490 4491bool TargetProperties::GetUseDIL(ExecutionContext *exe_ctx) const {4492 const Property *exp_property =4493 m_collection_sp->GetPropertyAtIndex(ePropertyExperimental, exe_ctx);4494 OptionValueProperties *exp_values =4495 exp_property->GetValue()->GetAsProperties();4496 if (exp_values)4497 return exp_values->GetPropertyAtIndexAs<bool>(ePropertyUseDIL, exe_ctx)4498 .value_or(false);4499 else4500 return true;4501}4502 4503void TargetProperties::SetUseDIL(ExecutionContext *exe_ctx, bool b) {4504 const Property *exp_property =4505 m_collection_sp->GetPropertyAtIndex(ePropertyExperimental, exe_ctx);4506 OptionValueProperties *exp_values =4507 exp_property->GetValue()->GetAsProperties();4508 if (exp_values)4509 exp_values->SetPropertyAtIndex(ePropertyUseDIL, true, exe_ctx);4510}4511 4512ArchSpec TargetProperties::GetDefaultArchitecture() const {4513 const uint32_t idx = ePropertyDefaultArch;4514 return GetPropertyAtIndexAs<ArchSpec>(idx, {});4515}4516 4517void TargetProperties::SetDefaultArchitecture(const ArchSpec &arch) {4518 const uint32_t idx = ePropertyDefaultArch;4519 SetPropertyAtIndex(idx, arch);4520}4521 4522bool TargetProperties::GetMoveToNearestCode() const {4523 const uint32_t idx = ePropertyMoveToNearestCode;4524 return GetPropertyAtIndexAs<bool>(4525 idx, g_target_properties[idx].default_uint_value != 0);4526}4527 4528lldb::DynamicValueType TargetProperties::GetPreferDynamicValue() const {4529 const uint32_t idx = ePropertyPreferDynamic;4530 return GetPropertyAtIndexAs<lldb::DynamicValueType>(4531 idx, static_cast<lldb::DynamicValueType>(4532 g_target_properties[idx].default_uint_value));4533}4534 4535bool TargetProperties::SetPreferDynamicValue(lldb::DynamicValueType d) {4536 const uint32_t idx = ePropertyPreferDynamic;4537 return SetPropertyAtIndex(idx, d);4538}4539 4540bool TargetProperties::GetPreloadSymbols() const {4541 if (INTERRUPT_REQUESTED(m_target->GetDebugger(),4542 "Interrupted checking preload symbols")) {4543 return false;4544 }4545 const uint32_t idx = ePropertyPreloadSymbols;4546 return GetPropertyAtIndexAs<bool>(4547 idx, g_target_properties[idx].default_uint_value != 0);4548}4549 4550void TargetProperties::SetPreloadSymbols(bool b) {4551 const uint32_t idx = ePropertyPreloadSymbols;4552 SetPropertyAtIndex(idx, b);4553}4554 4555bool TargetProperties::GetDisableASLR() const {4556 const uint32_t idx = ePropertyDisableASLR;4557 return GetPropertyAtIndexAs<bool>(4558 idx, g_target_properties[idx].default_uint_value != 0);4559}4560 4561void TargetProperties::SetDisableASLR(bool b) {4562 const uint32_t idx = ePropertyDisableASLR;4563 SetPropertyAtIndex(idx, b);4564}4565 4566bool TargetProperties::GetInheritTCC() const {4567 const uint32_t idx = ePropertyInheritTCC;4568 return GetPropertyAtIndexAs<bool>(4569 idx, g_target_properties[idx].default_uint_value != 0);4570}4571 4572void TargetProperties::SetInheritTCC(bool b) {4573 const uint32_t idx = ePropertyInheritTCC;4574 SetPropertyAtIndex(idx, b);4575}4576 4577bool TargetProperties::GetDetachOnError() const {4578 const uint32_t idx = ePropertyDetachOnError;4579 return GetPropertyAtIndexAs<bool>(4580 idx, g_target_properties[idx].default_uint_value != 0);4581}4582 4583void TargetProperties::SetDetachOnError(bool b) {4584 const uint32_t idx = ePropertyDetachOnError;4585 SetPropertyAtIndex(idx, b);4586}4587 4588bool TargetProperties::GetDisableSTDIO() const {4589 const uint32_t idx = ePropertyDisableSTDIO;4590 return GetPropertyAtIndexAs<bool>(4591 idx, g_target_properties[idx].default_uint_value != 0);4592}4593 4594void TargetProperties::SetDisableSTDIO(bool b) {4595 const uint32_t idx = ePropertyDisableSTDIO;4596 SetPropertyAtIndex(idx, b);4597}4598llvm::StringRef TargetProperties::GetLaunchWorkingDirectory() const {4599 const uint32_t idx = ePropertyLaunchWorkingDir;4600 return GetPropertyAtIndexAs<llvm::StringRef>(4601 idx, g_target_properties[idx].default_cstr_value);4602}4603 4604bool TargetProperties::GetParallelModuleLoad() const {4605 const uint32_t idx = ePropertyParallelModuleLoad;4606 return GetPropertyAtIndexAs<bool>(4607 idx, g_target_properties[idx].default_uint_value != 0);4608}4609 4610const char *TargetProperties::GetDisassemblyFlavor() const {4611 const uint32_t idx = ePropertyDisassemblyFlavor;4612 const char *return_value;4613 4614 x86DisassemblyFlavor flavor_value =4615 GetPropertyAtIndexAs<x86DisassemblyFlavor>(4616 idx, static_cast<x86DisassemblyFlavor>(4617 g_target_properties[idx].default_uint_value));4618 4619 return_value = g_x86_dis_flavor_value_types[flavor_value].string_value;4620 return return_value;4621}4622 4623const char *TargetProperties::GetDisassemblyCPU() const {4624 const uint32_t idx = ePropertyDisassemblyCPU;4625 llvm::StringRef str = GetPropertyAtIndexAs<llvm::StringRef>(4626 idx, g_target_properties[idx].default_cstr_value);4627 return str.empty() ? nullptr : str.data();4628}4629 4630const char *TargetProperties::GetDisassemblyFeatures() const {4631 const uint32_t idx = ePropertyDisassemblyFeatures;4632 llvm::StringRef str = GetPropertyAtIndexAs<llvm::StringRef>(4633 idx, g_target_properties[idx].default_cstr_value);4634 return str.empty() ? nullptr : str.data();4635}4636 4637InlineStrategy TargetProperties::GetInlineStrategy() const {4638 const uint32_t idx = ePropertyInlineStrategy;4639 return GetPropertyAtIndexAs<InlineStrategy>(4640 idx,4641 static_cast<InlineStrategy>(g_target_properties[idx].default_uint_value));4642}4643 4644// Returning RealpathPrefixes, but the setting's type is FileSpecList. We do4645// this because we want the FileSpecList to normalize the file paths for us.4646RealpathPrefixes TargetProperties::GetSourceRealpathPrefixes() const {4647 const uint32_t idx = ePropertySourceRealpathPrefixes;4648 return RealpathPrefixes(GetPropertyAtIndexAs<FileSpecList>(idx, {}));4649}4650 4651llvm::StringRef TargetProperties::GetArg0() const {4652 const uint32_t idx = ePropertyArg0;4653 return GetPropertyAtIndexAs<llvm::StringRef>(4654 idx, g_target_properties[idx].default_cstr_value);4655}4656 4657void TargetProperties::SetArg0(llvm::StringRef arg) {4658 const uint32_t idx = ePropertyArg0;4659 SetPropertyAtIndex(idx, arg);4660 m_launch_info.SetArg0(arg);4661}4662 4663bool TargetProperties::GetRunArguments(Args &args) const {4664 const uint32_t idx = ePropertyRunArgs;4665 return m_collection_sp->GetPropertyAtIndexAsArgs(idx, args);4666}4667 4668void TargetProperties::SetRunArguments(const Args &args) {4669 const uint32_t idx = ePropertyRunArgs;4670 m_collection_sp->SetPropertyAtIndexFromArgs(idx, args);4671 m_launch_info.GetArguments() = args;4672}4673 4674Environment TargetProperties::ComputeEnvironment() const {4675 Environment env;4676 4677 if (m_target &&4678 GetPropertyAtIndexAs<bool>(4679 ePropertyInheritEnv,4680 g_target_properties[ePropertyInheritEnv].default_uint_value != 0)) {4681 if (auto platform_sp = m_target->GetPlatform()) {4682 Environment platform_env = platform_sp->GetEnvironment();4683 for (const auto &KV : platform_env)4684 env[KV.first()] = KV.second;4685 }4686 }4687 4688 Args property_unset_env;4689 m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyUnsetEnvVars,4690 property_unset_env);4691 for (const auto &var : property_unset_env)4692 env.erase(var.ref());4693 4694 Args property_env;4695 m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyEnvVars, property_env);4696 for (const auto &KV : Environment(property_env))4697 env[KV.first()] = KV.second;4698 4699 return env;4700}4701 4702Environment TargetProperties::GetEnvironment() const {4703 return ComputeEnvironment();4704}4705 4706Environment TargetProperties::GetInheritedEnvironment() const {4707 Environment environment;4708 4709 if (m_target == nullptr)4710 return environment;4711 4712 if (!GetPropertyAtIndexAs<bool>(4713 ePropertyInheritEnv,4714 g_target_properties[ePropertyInheritEnv].default_uint_value != 0))4715 return environment;4716 4717 PlatformSP platform_sp = m_target->GetPlatform();4718 if (platform_sp == nullptr)4719 return environment;4720 4721 Environment platform_environment = platform_sp->GetEnvironment();4722 for (const auto &KV : platform_environment)4723 environment[KV.first()] = KV.second;4724 4725 Args property_unset_environment;4726 m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyUnsetEnvVars,4727 property_unset_environment);4728 for (const auto &var : property_unset_environment)4729 environment.erase(var.ref());4730 4731 return environment;4732}4733 4734Environment TargetProperties::GetTargetEnvironment() const {4735 Args property_environment;4736 m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyEnvVars,4737 property_environment);4738 Environment environment;4739 for (const auto &KV : Environment(property_environment))4740 environment[KV.first()] = KV.second;4741 4742 return environment;4743}4744 4745void TargetProperties::SetEnvironment(Environment env) {4746 // TODO: Get rid of the Args intermediate step4747 const uint32_t idx = ePropertyEnvVars;4748 m_collection_sp->SetPropertyAtIndexFromArgs(idx, Args(env));4749}4750 4751bool TargetProperties::GetSkipPrologue() const {4752 const uint32_t idx = ePropertySkipPrologue;4753 return GetPropertyAtIndexAs<bool>(4754 idx, g_target_properties[idx].default_uint_value != 0);4755}4756 4757PathMappingList &TargetProperties::GetSourcePathMap() const {4758 const uint32_t idx = ePropertySourceMap;4759 OptionValuePathMappings *option_value =4760 m_collection_sp->GetPropertyAtIndexAsOptionValuePathMappings(idx);4761 assert(option_value);4762 return option_value->GetCurrentValue();4763}4764 4765PathMappingList &TargetProperties::GetObjectPathMap() const {4766 const uint32_t idx = ePropertyObjectMap;4767 OptionValuePathMappings *option_value =4768 m_collection_sp->GetPropertyAtIndexAsOptionValuePathMappings(idx);4769 assert(option_value);4770 return option_value->GetCurrentValue();4771}4772 4773bool TargetProperties::GetAutoSourceMapRelative() const {4774 const uint32_t idx = ePropertyAutoSourceMapRelative;4775 return GetPropertyAtIndexAs<bool>(4776 idx, g_target_properties[idx].default_uint_value != 0);4777}4778 4779void TargetProperties::AppendExecutableSearchPaths(const FileSpec &dir) {4780 const uint32_t idx = ePropertyExecutableSearchPaths;4781 OptionValueFileSpecList *option_value =4782 m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(idx);4783 assert(option_value);4784 option_value->AppendCurrentValue(dir);4785}4786 4787FileSpecList TargetProperties::GetExecutableSearchPaths() {4788 const uint32_t idx = ePropertyExecutableSearchPaths;4789 return GetPropertyAtIndexAs<FileSpecList>(idx, {});4790}4791 4792FileSpecList TargetProperties::GetDebugFileSearchPaths() {4793 const uint32_t idx = ePropertyDebugFileSearchPaths;4794 return GetPropertyAtIndexAs<FileSpecList>(idx, {});4795}4796 4797FileSpecList TargetProperties::GetClangModuleSearchPaths() {4798 const uint32_t idx = ePropertyClangModuleSearchPaths;4799 return GetPropertyAtIndexAs<FileSpecList>(idx, {});4800}4801 4802bool TargetProperties::GetEnableAutoImportClangModules() const {4803 const uint32_t idx = ePropertyAutoImportClangModules;4804 return GetPropertyAtIndexAs<bool>(4805 idx, g_target_properties[idx].default_uint_value != 0);4806}4807 4808ImportStdModule TargetProperties::GetImportStdModule() const {4809 const uint32_t idx = ePropertyImportStdModule;4810 return GetPropertyAtIndexAs<ImportStdModule>(4811 idx, static_cast<ImportStdModule>(4812 g_target_properties[idx].default_uint_value));4813}4814 4815DynamicClassInfoHelper TargetProperties::GetDynamicClassInfoHelper() const {4816 const uint32_t idx = ePropertyDynamicClassInfoHelper;4817 return GetPropertyAtIndexAs<DynamicClassInfoHelper>(4818 idx, static_cast<DynamicClassInfoHelper>(4819 g_target_properties[idx].default_uint_value));4820}4821 4822bool TargetProperties::GetEnableAutoApplyFixIts() const {4823 const uint32_t idx = ePropertyAutoApplyFixIts;4824 return GetPropertyAtIndexAs<bool>(4825 idx, g_target_properties[idx].default_uint_value != 0);4826}4827 4828uint64_t TargetProperties::GetNumberOfRetriesWithFixits() const {4829 const uint32_t idx = ePropertyRetriesWithFixIts;4830 return GetPropertyAtIndexAs<uint64_t>(4831 idx, g_target_properties[idx].default_uint_value);4832}4833 4834bool TargetProperties::GetEnableNotifyAboutFixIts() const {4835 const uint32_t idx = ePropertyNotifyAboutFixIts;4836 return GetPropertyAtIndexAs<bool>(4837 idx, g_target_properties[idx].default_uint_value != 0);4838}4839 4840FileSpec TargetProperties::GetSaveJITObjectsDir() const {4841 const uint32_t idx = ePropertySaveObjectsDir;4842 return GetPropertyAtIndexAs<FileSpec>(idx, {});4843}4844 4845void TargetProperties::CheckJITObjectsDir() {4846 FileSpec new_dir = GetSaveJITObjectsDir();4847 if (!new_dir)4848 return;4849 4850 const FileSystem &instance = FileSystem::Instance();4851 bool exists = instance.Exists(new_dir);4852 bool is_directory = instance.IsDirectory(new_dir);4853 std::string path = new_dir.GetPath(true);4854 bool writable = llvm::sys::fs::can_write(path);4855 if (exists && is_directory && writable)4856 return;4857 4858 m_collection_sp->GetPropertyAtIndex(ePropertySaveObjectsDir)4859 ->GetValue()4860 ->Clear();4861 4862 std::string buffer;4863 llvm::raw_string_ostream os(buffer);4864 os << "JIT object dir '" << path << "' ";4865 if (!exists)4866 os << "does not exist";4867 else if (!is_directory)4868 os << "is not a directory";4869 else if (!writable)4870 os << "is not writable";4871 4872 std::optional<lldb::user_id_t> debugger_id;4873 if (m_target)4874 debugger_id = m_target->GetDebugger().GetID();4875 Debugger::ReportError(buffer, debugger_id);4876}4877 4878bool TargetProperties::GetEnableSyntheticValue() const {4879 const uint32_t idx = ePropertyEnableSynthetic;4880 return GetPropertyAtIndexAs<bool>(4881 idx, g_target_properties[idx].default_uint_value != 0);4882}4883 4884bool TargetProperties::ShowHexVariableValuesWithLeadingZeroes() const {4885 const uint32_t idx = ePropertyShowHexVariableValuesWithLeadingZeroes;4886 return GetPropertyAtIndexAs<bool>(4887 idx, g_target_properties[idx].default_uint_value != 0);4888}4889 4890uint32_t TargetProperties::GetMaxZeroPaddingInFloatFormat() const {4891 const uint32_t idx = ePropertyMaxZeroPaddingInFloatFormat;4892 return GetPropertyAtIndexAs<uint64_t>(4893 idx, g_target_properties[idx].default_uint_value);4894}4895 4896uint32_t TargetProperties::GetMaximumNumberOfChildrenToDisplay() const {4897 const uint32_t idx = ePropertyMaxChildrenCount;4898 return GetPropertyAtIndexAs<uint64_t>(4899 idx, g_target_properties[idx].default_uint_value);4900}4901 4902std::pair<uint32_t, bool>4903TargetProperties::GetMaximumDepthOfChildrenToDisplay() const {4904 const uint32_t idx = ePropertyMaxChildrenDepth;4905 auto *option_value =4906 m_collection_sp->GetPropertyAtIndexAsOptionValueUInt64(idx);4907 bool is_default = !option_value->OptionWasSet();4908 return {option_value->GetCurrentValue(), is_default};4909}4910 4911uint32_t TargetProperties::GetMaximumSizeOfStringSummary() const {4912 const uint32_t idx = ePropertyMaxSummaryLength;4913 return GetPropertyAtIndexAs<uint64_t>(4914 idx, g_target_properties[idx].default_uint_value);4915}4916 4917uint32_t TargetProperties::GetMaximumMemReadSize() const {4918 const uint32_t idx = ePropertyMaxMemReadSize;4919 return GetPropertyAtIndexAs<uint64_t>(4920 idx, g_target_properties[idx].default_uint_value);4921}4922 4923FileSpec TargetProperties::GetStandardInputPath() const {4924 const uint32_t idx = ePropertyInputPath;4925 return GetPropertyAtIndexAs<FileSpec>(idx, {});4926}4927 4928void TargetProperties::SetStandardInputPath(llvm::StringRef path) {4929 const uint32_t idx = ePropertyInputPath;4930 SetPropertyAtIndex(idx, path);4931}4932 4933FileSpec TargetProperties::GetStandardOutputPath() const {4934 const uint32_t idx = ePropertyOutputPath;4935 return GetPropertyAtIndexAs<FileSpec>(idx, {});4936}4937 4938void TargetProperties::SetStandardOutputPath(llvm::StringRef path) {4939 const uint32_t idx = ePropertyOutputPath;4940 SetPropertyAtIndex(idx, path);4941}4942 4943FileSpec TargetProperties::GetStandardErrorPath() const {4944 const uint32_t idx = ePropertyErrorPath;4945 return GetPropertyAtIndexAs<FileSpec>(idx, {});4946}4947 4948void TargetProperties::SetStandardErrorPath(llvm::StringRef path) {4949 const uint32_t idx = ePropertyErrorPath;4950 SetPropertyAtIndex(idx, path);4951}4952 4953SourceLanguage TargetProperties::GetLanguage() const {4954 const uint32_t idx = ePropertyLanguage;4955 return SourceLanguage{GetPropertyAtIndexAs<LanguageType>(idx, {})};4956}4957 4958llvm::StringRef TargetProperties::GetExpressionPrefixContents() {4959 const uint32_t idx = ePropertyExprPrefix;4960 OptionValueFileSpec *file =4961 m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpec(idx);4962 if (file) {4963 DataBufferSP data_sp(file->GetFileContents());4964 if (data_sp)4965 return llvm::StringRef(4966 reinterpret_cast<const char *>(data_sp->GetBytes()),4967 data_sp->GetByteSize());4968 }4969 return "";4970}4971 4972uint64_t TargetProperties::GetExprErrorLimit() const {4973 const uint32_t idx = ePropertyExprErrorLimit;4974 return GetPropertyAtIndexAs<uint64_t>(4975 idx, g_target_properties[idx].default_uint_value);4976}4977 4978uint64_t TargetProperties::GetExprAllocAddress() const {4979 const uint32_t idx = ePropertyExprAllocAddress;4980 return GetPropertyAtIndexAs<uint64_t>(4981 idx, g_target_properties[idx].default_uint_value);4982}4983 4984uint64_t TargetProperties::GetExprAllocSize() const {4985 const uint32_t idx = ePropertyExprAllocSize;4986 return GetPropertyAtIndexAs<uint64_t>(4987 idx, g_target_properties[idx].default_uint_value);4988}4989 4990uint64_t TargetProperties::GetExprAllocAlign() const {4991 const uint32_t idx = ePropertyExprAllocAlign;4992 return GetPropertyAtIndexAs<uint64_t>(4993 idx, g_target_properties[idx].default_uint_value);4994}4995 4996bool TargetProperties::GetBreakpointsConsultPlatformAvoidList() {4997 const uint32_t idx = ePropertyBreakpointUseAvoidList;4998 return GetPropertyAtIndexAs<bool>(4999 idx, g_target_properties[idx].default_uint_value != 0);5000}5001 5002bool TargetProperties::GetUseHexImmediates() const {5003 const uint32_t idx = ePropertyUseHexImmediates;5004 return GetPropertyAtIndexAs<bool>(5005 idx, g_target_properties[idx].default_uint_value != 0);5006}5007 5008bool TargetProperties::GetUseFastStepping() const {5009 const uint32_t idx = ePropertyUseFastStepping;5010 return GetPropertyAtIndexAs<bool>(5011 idx, g_target_properties[idx].default_uint_value != 0);5012}5013 5014bool TargetProperties::GetDisplayExpressionsInCrashlogs() const {5015 const uint32_t idx = ePropertyDisplayExpressionsInCrashlogs;5016 return GetPropertyAtIndexAs<bool>(5017 idx, g_target_properties[idx].default_uint_value != 0);5018}5019 5020LoadScriptFromSymFile TargetProperties::GetLoadScriptFromSymbolFile() const {5021 const uint32_t idx = ePropertyLoadScriptFromSymbolFile;5022 return GetPropertyAtIndexAs<LoadScriptFromSymFile>(5023 idx, static_cast<LoadScriptFromSymFile>(5024 g_target_properties[idx].default_uint_value));5025}5026 5027LoadCWDlldbinitFile TargetProperties::GetLoadCWDlldbinitFile() const {5028 const uint32_t idx = ePropertyLoadCWDlldbinitFile;5029 return GetPropertyAtIndexAs<LoadCWDlldbinitFile>(5030 idx, static_cast<LoadCWDlldbinitFile>(5031 g_target_properties[idx].default_uint_value));5032}5033 5034Disassembler::HexImmediateStyle TargetProperties::GetHexImmediateStyle() const {5035 const uint32_t idx = ePropertyHexImmediateStyle;5036 return GetPropertyAtIndexAs<Disassembler::HexImmediateStyle>(5037 idx, static_cast<Disassembler::HexImmediateStyle>(5038 g_target_properties[idx].default_uint_value));5039}5040 5041MemoryModuleLoadLevel TargetProperties::GetMemoryModuleLoadLevel() const {5042 const uint32_t idx = ePropertyMemoryModuleLoadLevel;5043 return GetPropertyAtIndexAs<MemoryModuleLoadLevel>(5044 idx, static_cast<MemoryModuleLoadLevel>(5045 g_target_properties[idx].default_uint_value));5046}5047 5048bool TargetProperties::GetUserSpecifiedTrapHandlerNames(Args &args) const {5049 const uint32_t idx = ePropertyTrapHandlerNames;5050 return m_collection_sp->GetPropertyAtIndexAsArgs(idx, args);5051}5052 5053void TargetProperties::SetUserSpecifiedTrapHandlerNames(const Args &args) {5054 const uint32_t idx = ePropertyTrapHandlerNames;5055 m_collection_sp->SetPropertyAtIndexFromArgs(idx, args);5056}5057 5058bool TargetProperties::GetDisplayRuntimeSupportValues() const {5059 const uint32_t idx = ePropertyDisplayRuntimeSupportValues;5060 return GetPropertyAtIndexAs<bool>(5061 idx, g_target_properties[idx].default_uint_value != 0);5062}5063 5064void TargetProperties::SetDisplayRuntimeSupportValues(bool b) {5065 const uint32_t idx = ePropertyDisplayRuntimeSupportValues;5066 SetPropertyAtIndex(idx, b);5067}5068 5069bool TargetProperties::GetDisplayRecognizedArguments() const {5070 const uint32_t idx = ePropertyDisplayRecognizedArguments;5071 return GetPropertyAtIndexAs<bool>(5072 idx, g_target_properties[idx].default_uint_value != 0);5073}5074 5075void TargetProperties::SetDisplayRecognizedArguments(bool b) {5076 const uint32_t idx = ePropertyDisplayRecognizedArguments;5077 SetPropertyAtIndex(idx, b);5078}5079 5080const ProcessLaunchInfo &TargetProperties::GetProcessLaunchInfo() const {5081 return m_launch_info;5082}5083 5084void TargetProperties::SetProcessLaunchInfo(5085 const ProcessLaunchInfo &launch_info) {5086 m_launch_info = launch_info;5087 SetArg0(launch_info.GetArg0());5088 SetRunArguments(launch_info.GetArguments());5089 SetEnvironment(launch_info.GetEnvironment());5090 const FileAction *input_file_action =5091 launch_info.GetFileActionForFD(STDIN_FILENO);5092 if (input_file_action) {5093 SetStandardInputPath(input_file_action->GetPath());5094 }5095 const FileAction *output_file_action =5096 launch_info.GetFileActionForFD(STDOUT_FILENO);5097 if (output_file_action) {5098 SetStandardOutputPath(output_file_action->GetPath());5099 }5100 const FileAction *error_file_action =5101 launch_info.GetFileActionForFD(STDERR_FILENO);5102 if (error_file_action) {5103 SetStandardErrorPath(error_file_action->GetPath());5104 }5105 SetDetachOnError(launch_info.GetFlags().Test(lldb::eLaunchFlagDetachOnError));5106 SetDisableASLR(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableASLR));5107 SetInheritTCC(5108 launch_info.GetFlags().Test(lldb::eLaunchFlagInheritTCCFromParent));5109 SetDisableSTDIO(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableSTDIO));5110}5111 5112bool TargetProperties::GetRequireHardwareBreakpoints() const {5113 const uint32_t idx = ePropertyRequireHardwareBreakpoints;5114 return GetPropertyAtIndexAs<bool>(5115 idx, g_target_properties[idx].default_uint_value != 0);5116}5117 5118void TargetProperties::SetRequireHardwareBreakpoints(bool b) {5119 const uint32_t idx = ePropertyRequireHardwareBreakpoints;5120 m_collection_sp->SetPropertyAtIndex(idx, b);5121}5122 5123bool TargetProperties::GetAutoInstallMainExecutable() const {5124 const uint32_t idx = ePropertyAutoInstallMainExecutable;5125 return GetPropertyAtIndexAs<bool>(5126 idx, g_target_properties[idx].default_uint_value != 0);5127}5128 5129void TargetProperties::Arg0ValueChangedCallback() {5130 m_launch_info.SetArg0(GetArg0());5131}5132 5133void TargetProperties::RunArgsValueChangedCallback() {5134 Args args;5135 if (GetRunArguments(args))5136 m_launch_info.GetArguments() = args;5137}5138 5139void TargetProperties::EnvVarsValueChangedCallback() {5140 m_launch_info.GetEnvironment() = ComputeEnvironment();5141}5142 5143void TargetProperties::InputPathValueChangedCallback() {5144 m_launch_info.AppendOpenFileAction(STDIN_FILENO, GetStandardInputPath(), true,5145 false);5146}5147 5148void TargetProperties::OutputPathValueChangedCallback() {5149 m_launch_info.AppendOpenFileAction(STDOUT_FILENO, GetStandardOutputPath(),5150 false, true);5151}5152 5153void TargetProperties::ErrorPathValueChangedCallback() {5154 m_launch_info.AppendOpenFileAction(STDERR_FILENO, GetStandardErrorPath(),5155 false, true);5156}5157 5158void TargetProperties::DetachOnErrorValueChangedCallback() {5159 if (GetDetachOnError())5160 m_launch_info.GetFlags().Set(lldb::eLaunchFlagDetachOnError);5161 else5162 m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDetachOnError);5163}5164 5165void TargetProperties::DisableASLRValueChangedCallback() {5166 if (GetDisableASLR())5167 m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableASLR);5168 else5169 m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableASLR);5170}5171 5172void TargetProperties::InheritTCCValueChangedCallback() {5173 if (GetInheritTCC())5174 m_launch_info.GetFlags().Set(lldb::eLaunchFlagInheritTCCFromParent);5175 else5176 m_launch_info.GetFlags().Clear(lldb::eLaunchFlagInheritTCCFromParent);5177}5178 5179void TargetProperties::DisableSTDIOValueChangedCallback() {5180 if (GetDisableSTDIO())5181 m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableSTDIO);5182 else5183 m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableSTDIO);5184}5185 5186bool TargetProperties::GetDebugUtilityExpression() const {5187 const uint32_t idx = ePropertyDebugUtilityExpression;5188 return GetPropertyAtIndexAs<bool>(5189 idx, g_target_properties[idx].default_uint_value != 0);5190}5191 5192void TargetProperties::SetDebugUtilityExpression(bool debug) {5193 const uint32_t idx = ePropertyDebugUtilityExpression;5194 SetPropertyAtIndex(idx, debug);5195}5196 5197// Target::TargetEventData5198 5199Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp)5200 : EventData(), m_target_sp(target_sp), m_module_list() {}5201 5202Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp,5203 const ModuleList &module_list)5204 : EventData(), m_target_sp(target_sp), m_module_list(module_list) {}5205 5206Target::TargetEventData::TargetEventData(5207 const lldb::TargetSP &target_sp, const lldb::TargetSP &created_target_sp)5208 : EventData(), m_target_sp(target_sp),5209 m_created_target_sp(created_target_sp), m_module_list() {}5210 5211Target::TargetEventData::~TargetEventData() = default;5212 5213llvm::StringRef Target::TargetEventData::GetFlavorString() {5214 return "Target::TargetEventData";5215}5216 5217void Target::TargetEventData::Dump(Stream *s) const {5218 for (size_t i = 0; i < m_module_list.GetSize(); ++i) {5219 if (i != 0)5220 *s << ", ";5221 m_module_list.GetModuleAtIndex(i)->GetDescription(5222 s->AsRawOstream(), lldb::eDescriptionLevelBrief);5223 }5224}5225 5226const Target::TargetEventData *5227Target::TargetEventData::GetEventDataFromEvent(const Event *event_ptr) {5228 if (event_ptr) {5229 const EventData *event_data = event_ptr->GetData();5230 if (event_data &&5231 event_data->GetFlavor() == TargetEventData::GetFlavorString())5232 return static_cast<const TargetEventData *>(event_ptr->GetData());5233 }5234 return nullptr;5235}5236 5237TargetSP Target::TargetEventData::GetTargetFromEvent(const Event *event_ptr) {5238 TargetSP target_sp;5239 const TargetEventData *event_data = GetEventDataFromEvent(event_ptr);5240 if (event_data)5241 target_sp = event_data->m_target_sp;5242 return target_sp;5243}5244 5245TargetSP5246Target::TargetEventData::GetCreatedTargetFromEvent(const Event *event_ptr) {5247 TargetSP created_target_sp;5248 const TargetEventData *event_data = GetEventDataFromEvent(event_ptr);5249 if (event_data)5250 created_target_sp = event_data->m_created_target_sp;5251 return created_target_sp;5252}5253 5254ModuleList5255Target::TargetEventData::GetModuleListFromEvent(const Event *event_ptr) {5256 ModuleList module_list;5257 const TargetEventData *event_data = GetEventDataFromEvent(event_ptr);5258 if (event_data)5259 module_list = event_data->m_module_list;5260 return module_list;5261}5262 5263std::recursive_mutex &Target::GetAPIMutex() {5264 if (GetProcessSP() && GetProcessSP()->CurrentThreadIsPrivateStateThread())5265 return m_private_mutex;5266 else5267 return m_mutex;5268}5269 5270/// Get metrics associated with this target in JSON format.5271llvm::json::Value5272Target::ReportStatistics(const lldb_private::StatisticsOptions &options) {5273 return m_stats.ToJSON(*this, options);5274}5275 5276void Target::ResetStatistics() { m_stats.Reset(*this); }5277 5278bool Target::HasLoadedSections() { return !GetSectionLoadList().IsEmpty(); }5279 5280lldb::addr_t Target::GetSectionLoadAddress(const lldb::SectionSP §ion_sp) {5281 return GetSectionLoadList().GetSectionLoadAddress(section_sp);5282}5283 5284void Target::ClearSectionLoadList() { GetSectionLoadList().Clear(); }5285 5286void Target::DumpSectionLoadList(Stream &s) {5287 GetSectionLoadList().Dump(s, this);5288}5289 5290void Target::NotifyBreakpointChanged(Breakpoint &bp,5291 lldb::BreakpointEventType eventKind) {5292 if (EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) {5293 std::shared_ptr<Breakpoint::BreakpointEventData> data_sp =5294 std::make_shared<Breakpoint::BreakpointEventData>(5295 eventKind, bp.shared_from_this());5296 BroadcastEvent(Target::eBroadcastBitBreakpointChanged, data_sp);5297 }5298}5299 5300void Target::NotifyBreakpointChanged(5301 Breakpoint &bp, const lldb::EventDataSP &breakpoint_data_sp) {5302 if (EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))5303 BroadcastEvent(Target::eBroadcastBitBreakpointChanged, breakpoint_data_sp);5304}5305