diff options
Diffstat (limited to 'source/Target/Target.cpp')
-rw-r--r-- | source/Target/Target.cpp | 293 |
1 files changed, 161 insertions, 132 deletions
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp index 437f92abdab3..4941cb585c55 100644 --- a/source/Target/Target.cpp +++ b/source/Target/Target.cpp @@ -1,17 +1,15 @@ //===-- Target.cpp ----------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "lldb/Target/Target.h" -#include "Plugins/ExpressionParser/Clang/ClangASTSource.h" #include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h" -#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" #include "lldb/Breakpoint/BreakpointIDList.h" +#include "lldb/Breakpoint/BreakpointPrecondition.h" #include "lldb/Breakpoint/BreakpointResolver.h" #include "lldb/Breakpoint/BreakpointResolverAddress.h" #include "lldb/Breakpoint/BreakpointResolverFileLine.h" @@ -39,12 +37,12 @@ #include "lldb/Interpreter/OptionValues.h" #include "lldb/Interpreter/Property.h" #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/ClangASTImporter.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/Language.h" #include "lldb/Target/LanguageRuntime.h" -#include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/StackFrame.h" @@ -58,6 +56,10 @@ #include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" + +#include "llvm/ADT/ScopeExit.h" + +#include <memory> #include <mutex> using namespace lldb; @@ -90,7 +92,7 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, m_breakpoint_list(false), m_internal_breakpoint_list(true), m_watchpoint_list(), m_process_sp(), m_search_filter_sp(), m_image_search_paths(ImageSearchPathsChanged, this), m_ast_importer_sp(), - m_source_manager_ap(), m_stop_hooks(), m_stop_hook_next_id(0), + m_source_manager_up(), m_stop_hooks(), m_stop_hook_next_id(0), m_valid(true), m_suppress_stop_hooks(false), m_is_dummy_target(is_dummy_target), m_stats_storage(static_cast<int>(StatisticKind::StatisticMax)) @@ -498,12 +500,13 @@ Target::GetSearchFilterForModule(const FileSpec *containingModule) { if (containingModule != nullptr) { // TODO: We should look into sharing module based search filters // across many breakpoints like we do for the simple target based one - filter_sp.reset( - new SearchFilterByModule(shared_from_this(), *containingModule)); + filter_sp = std::make_shared<SearchFilterByModule>(shared_from_this(), + *containingModule); } else { if (!m_search_filter_sp) - m_search_filter_sp.reset( - new SearchFilterForUnconstrainedSearches(shared_from_this())); + m_search_filter_sp = + std::make_shared<SearchFilterForUnconstrainedSearches>( + shared_from_this()); filter_sp = m_search_filter_sp; } return filter_sp; @@ -515,12 +518,13 @@ Target::GetSearchFilterForModuleList(const FileSpecList *containingModules) { if (containingModules && containingModules->GetSize() != 0) { // TODO: We should look into sharing module based search filters // across many breakpoints like we do for the simple target based one - filter_sp.reset( - new SearchFilterByModuleList(shared_from_this(), *containingModules)); + filter_sp = std::make_shared<SearchFilterByModuleList>(shared_from_this(), + *containingModules); } else { if (!m_search_filter_sp) - m_search_filter_sp.reset( - new SearchFilterForUnconstrainedSearches(shared_from_this())); + m_search_filter_sp = + std::make_shared<SearchFilterForUnconstrainedSearches>( + shared_from_this()); filter_sp = m_search_filter_sp; } return filter_sp; @@ -537,11 +541,11 @@ SearchFilterSP Target::GetSearchFilterForModuleAndCUList( // We could make a special "CU List only SearchFilter". Better yet was if // these could be composable, but that will take a little reworking. - filter_sp.reset(new SearchFilterByModuleListAndCU( - shared_from_this(), FileSpecList(), *containingSourceFiles)); + filter_sp = std::make_shared<SearchFilterByModuleListAndCU>( + shared_from_this(), FileSpecList(), *containingSourceFiles); } else { - filter_sp.reset(new SearchFilterByModuleListAndCU( - shared_from_this(), *containingModules, *containingSourceFiles)); + filter_sp = std::make_shared<SearchFilterByModuleListAndCU>( + shared_from_this(), *containingModules, *containingSourceFiles); } return filter_sp; } @@ -569,8 +573,7 @@ Target::CreateExceptionBreakpoint(enum lldb::LanguageType language, BreakpointSP exc_bkpt_sp = LanguageRuntime::CreateExceptionBreakpoint( *this, language, catch_bp, throw_bp, internal); if (exc_bkpt_sp && additional_args) { - Breakpoint::BreakpointPreconditionSP precondition_sp = - exc_bkpt_sp->GetPrecondition(); + BreakpointPreconditionSP precondition_sp = exc_bkpt_sp->GetPrecondition(); if (precondition_sp && additional_args) { if (error) *error = precondition_sp->ConfigurePrecondition(*additional_args); @@ -605,19 +608,17 @@ Target::CreateScriptedBreakpoint(const llvm::StringRef class_name, } else if (has_modules) { filter_sp = GetSearchFilterForModuleList(containingModules); } else { - filter_sp.reset(new SearchFilterForUnconstrainedSearches(shared_from_this())); + filter_sp = std::make_shared<SearchFilterForUnconstrainedSearches>( + shared_from_this()); } StructuredDataImpl *extra_args_impl = new StructuredDataImpl(); if (extra_args_sp) extra_args_impl->SetObjectSP(extra_args_sp); - - BreakpointResolverSP resolver_sp(new - BreakpointResolverScripted(nullptr, class_name, - depth, - extra_args_impl, - *GetDebugger().GetCommandInterpreter() - .GetScriptInterpreter())); + + BreakpointResolverSP resolver_sp(new BreakpointResolverScripted( + nullptr, class_name, depth, extra_args_impl, + *GetDebugger().GetScriptInterpreter())); return CreateBreakpoint(filter_sp, resolver_sp, internal, false, true); } @@ -697,7 +698,7 @@ void Target::AddBreakpointName(BreakpointName *bp_name) { m_breakpoint_names.insert(std::make_pair(bp_name->GetName(), bp_name)); } -BreakpointName *Target::FindBreakpointName(const ConstString &name, +BreakpointName *Target::FindBreakpointName(ConstString name, bool can_create, Status &error) { @@ -722,7 +723,7 @@ BreakpointName *Target::FindBreakpointName(const ConstString &name, } void -Target::DeleteBreakpointName(const ConstString &name) +Target::DeleteBreakpointName(ConstString name) { BreakpointNameList::iterator iter = m_breakpoint_names.find(name); @@ -735,7 +736,7 @@ Target::DeleteBreakpointName(const ConstString &name) } void Target::RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp, - const ConstString &name) + ConstString name) { bp_sp->RemoveName(name.AsCString()); } @@ -848,7 +849,7 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size, } if (!wp_sp) { - wp_sp.reset(new Watchpoint(*this, addr, size, type)); + wp_sp = std::make_shared<Watchpoint>(*this, addr, size, type); wp_sp->SetWatchpointType(kind, notify); m_watchpoint_list.Add(wp_sp, true); } @@ -1025,7 +1026,7 @@ Status Target::SerializeBreakpointsToFile(const FileSpec &file, } if (!break_store_ptr) { - break_store_sp.reset(new StructuredData::Array()); + break_store_sp = std::make_shared<StructuredData::Array>(); break_store_ptr = break_store_sp.get(); } @@ -1438,7 +1439,8 @@ void Target::SetExecutableModule(ModuleSP &executable_sp, "Target::SetExecutableModule (executable = '%s')", executable_sp->GetFileSpec().GetPath().c_str()); - m_images.Append(executable_sp); // The first image is our executable file + const bool notify = true; + m_images.Append(executable_sp, notify); // The first image is our executable file // If we haven't set an architecture yet, reset our architecture based on // what we found in the executable module. @@ -1466,6 +1468,7 @@ void Target::SetExecutableModule(ModuleSP &executable_sp, } if (executable_objfile && load_dependents) { + ModuleList added_modules; executable_objfile->GetDependentModules(dependent_files); for (uint32_t i = 0; i < dependent_files.GetSize(); i++) { FileSpec dependent_file_spec( @@ -1478,13 +1481,16 @@ void Target::SetExecutableModule(ModuleSP &executable_sp, platform_dependent_file_spec = dependent_file_spec; ModuleSpec module_spec(platform_dependent_file_spec, m_arch.GetSpec()); - ModuleSP image_module_sp(GetSharedModule(module_spec)); + ModuleSP image_module_sp(GetOrCreateModule(module_spec, + false /* notify */)); if (image_module_sp) { + added_modules.AppendIfNeeded (image_module_sp, false); ObjectFile *objfile = image_module_sp->GetObjectFile(); if (objfile) objfile->GetDependentModules(dependent_files); } } + ModulesDidLoad(added_modules); } } } @@ -1565,8 +1571,9 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) { arch_spec.GetArchitectureName(), arch_spec.GetTriple().getTriple().c_str()); ModuleSpec module_spec(executable_sp->GetFileSpec(), other); + FileSpecList search_paths = GetExecutableSearchPaths(); Status error = ModuleList::GetSharedModule(module_spec, executable_sp, - &GetExecutableSearchPaths(), + &search_paths, nullptr, nullptr); if (!error.Fail() && executable_sp) { @@ -1602,20 +1609,19 @@ bool Target::MergeArchitecture(const ArchSpec &arch_spec) { return false; } -void Target::WillClearList(const ModuleList &module_list) {} +void Target::NotifyWillClearList(const ModuleList &module_list) {} -void Target::ModuleAdded(const ModuleList &module_list, +void Target::NotifyModuleAdded(const ModuleList &module_list, const ModuleSP &module_sp) { // A module is being added to this target for the first time if (m_valid) { ModuleList my_module_list; my_module_list.Append(module_sp); - LoadScriptingResourceForModule(module_sp, this); ModulesDidLoad(my_module_list); } } -void Target::ModuleRemoved(const ModuleList &module_list, +void Target::NotifyModuleRemoved(const ModuleList &module_list, const ModuleSP &module_sp) { // A module is being removed from this target. if (m_valid) { @@ -1625,7 +1631,7 @@ void Target::ModuleRemoved(const ModuleList &module_list, } } -void Target::ModuleUpdated(const ModuleList &module_list, +void Target::NotifyModuleUpdated(const ModuleList &module_list, const ModuleSP &old_module_sp, const ModuleSP &new_module_sp) { // A module is replacing an already added module @@ -1637,8 +1643,18 @@ void Target::ModuleUpdated(const ModuleList &module_list, } } +void Target::NotifyModulesRemoved(lldb_private::ModuleList &module_list) { + ModulesDidUnload (module_list, false); +} + + void Target::ModulesDidLoad(ModuleList &module_list) { - if (m_valid && module_list.GetSize()) { + const size_t num_images = module_list.GetSize(); + if (m_valid && num_images) { + for (size_t idx = 0; idx < num_images; ++idx) { + ModuleSP module_sp(module_list.GetModuleAtIndex(idx)); + LoadScriptingResourceForModule(module_sp, this); + } m_breakpoint_list.UpdateBreakpoints(module_list, true, false); m_internal_breakpoint_list.UpdateBreakpoints(module_list, true, false); if (m_process_sp) { @@ -1652,11 +1668,8 @@ void Target::ModulesDidLoad(ModuleList &module_list) { void Target::SymbolsDidLoad(ModuleList &module_list) { if (m_valid && module_list.GetSize()) { if (m_process_sp) { - LanguageRuntime *runtime = - m_process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); - if (runtime) { - ObjCLanguageRuntime *objc_runtime = (ObjCLanguageRuntime *)runtime; - objc_runtime->SymbolsDidLoad(module_list); + for (LanguageRuntime *runtime : m_process_sp->GetLanguageRuntimes()) { + runtime->SymbolsDidLoad(module_list); } } @@ -1840,7 +1853,7 @@ size_t Target::ReadCStringFromMemory(const Address &addr, std::string &out_str, out_str.clear(); addr_t curr_addr = addr.GetLoadAddress(this); Address address(addr); - while (1) { + while (true) { size_t length = ReadCStringFromMemory(address, buf, sizeof(buf), error); if (length == 0) break; @@ -1980,8 +1993,8 @@ bool Target::ReadPointerFromMemory(const Address &addr, bool prefer_file_cache, return false; } -ModuleSP Target::GetSharedModule(const ModuleSpec &module_spec, - Status *error_ptr) { +ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, + Status *error_ptr) { ModuleSP module_sp; Status error; @@ -1997,7 +2010,7 @@ ModuleSP Target::GetSharedModule(const ModuleSpec &module_spec, ModuleSP old_module_sp; // This will get filled in if we have a new version // of the library bool did_create_module = false; - + FileSpecList search_paths = GetExecutableSearchPaths(); // If there are image search path entries, try to use them first to acquire // a suitable image. if (m_image_search_paths.GetSize()) { @@ -2008,7 +2021,7 @@ ModuleSP Target::GetSharedModule(const ModuleSpec &module_spec, transformed_spec.GetFileSpec().GetFilename() = module_spec.GetFileSpec().GetFilename(); error = ModuleList::GetSharedModule(transformed_spec, module_sp, - &GetExecutableSearchPaths(), + &search_paths, &old_module_sp, &did_create_module); } } @@ -2025,7 +2038,7 @@ ModuleSP Target::GetSharedModule(const ModuleSpec &module_spec, if (module_spec.GetUUID().IsValid()) { // We have a UUID, it is OK to check the global module list... error = ModuleList::GetSharedModule(module_spec, module_sp, - &GetExecutableSearchPaths(), + &search_paths, &old_module_sp, &did_create_module); } @@ -2035,7 +2048,7 @@ ModuleSP Target::GetSharedModule(const ModuleSpec &module_spec, if (m_platform_sp) { error = m_platform_sp->GetSharedModule( module_spec, m_process_sp.get(), module_sp, - &GetExecutableSearchPaths(), &old_module_sp, &did_create_module); + &search_paths, &old_module_sp, &did_create_module); } else { error.SetErrorString("no platform is currently set"); } @@ -2114,8 +2127,9 @@ ModuleSP Target::GetSharedModule(const ModuleSpec &module_spec, Module *old_module_ptr = old_module_sp.get(); old_module_sp.reset(); ModuleList::RemoveSharedModuleIfOrphaned(old_module_ptr); - } else - m_images.Append(module_sp); + } else { + m_images.Append(module_sp, notify); + } } else module_sp.reset(); } @@ -2200,7 +2214,8 @@ Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) { UserExpression *Target::GetUserExpressionForLanguage( llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, Expression::ResultType desired_type, - const EvaluateExpressionOptions &options, Status &error) { + const EvaluateExpressionOptions &options, + ValueObject *ctx_obj, Status &error) { Status type_system_error; TypeSystem *type_system = @@ -2216,7 +2231,7 @@ UserExpression *Target::GetUserExpressionForLanguage( } user_expr = type_system->GetUserExpression(expr, prefix, language, - desired_type, options); + desired_type, options, ctx_obj); if (!user_expr) error.SetErrorStringWithFormat( "Could not create an expression for language %s", @@ -2290,7 +2305,7 @@ ClangASTContext *Target::GetScratchClangASTContext(bool create_on_demand) { ClangASTImporterSP Target::GetClangASTImporter() { if (m_valid) { if (!m_ast_importer_sp) { - m_ast_importer_sp.reset(new ClangASTImporter()); + m_ast_importer_sp = std::make_shared<ClangASTImporter>(); } return m_ast_importer_sp; } @@ -2315,13 +2330,6 @@ FileSpecList Target::GetDefaultDebugFileSearchPaths() { return FileSpecList(); } -FileSpecList Target::GetDefaultClangModuleSearchPaths() { - TargetPropertiesSP properties_sp(Target::GetGlobalProperties()); - if (properties_sp) - return properties_sp->GetClangModuleSearchPaths(); - return FileSpecList(); -} - ArchSpec Target::GetDefaultArchitecture() { TargetPropertiesSP properties_sp(Target::GetGlobalProperties()); if (properties_sp) @@ -2357,7 +2365,8 @@ Target *Target::GetTargetFromContexts(const ExecutionContext *exe_ctx_ptr, ExpressionResults Target::EvaluateExpression( llvm::StringRef expr, ExecutionContextScope *exe_scope, lldb::ValueObjectSP &result_valobj_sp, - const EvaluateExpressionOptions &options, std::string *fixed_expression) { + const EvaluateExpressionOptions &options, std::string *fixed_expression, + ValueObject *ctx_obj) { result_valobj_sp.reset(); ExpressionResults execution_results = eExpressionSetupError; @@ -2365,10 +2374,11 @@ ExpressionResults Target::EvaluateExpression( if (expr.empty()) return execution_results; - // We shouldn't run stop hooks in expressions. Be sure to reset this if you - // return anywhere within this function. + // We shouldn't run stop hooks in expressions. bool old_suppress_value = m_suppress_stop_hooks; m_suppress_stop_hooks = true; + auto on_exit = llvm::make_scope_exit([this, old_suppress_value]() { + m_suppress_stop_hooks = old_suppress_value; }); ExecutionContext exe_ctx; @@ -2395,19 +2405,18 @@ ExpressionResults Target::EvaluateExpression( } else { llvm::StringRef prefix = GetExpressionPrefixContents(); Status error; - execution_results = UserExpression::Evaluate(exe_ctx, options, expr, prefix, - result_valobj_sp, error, - 0, // Line Number - fixed_expression); + execution_results = + UserExpression::Evaluate(exe_ctx, options, expr, prefix, + result_valobj_sp, error, fixed_expression, + nullptr, // Module + ctx_obj); } - m_suppress_stop_hooks = old_suppress_value; - return execution_results; } lldb::ExpressionVariableSP -Target::GetPersistentVariable(const ConstString &name) { +Target::GetPersistentVariable(ConstString name) { lldb::ExpressionVariableSP variable_sp; m_scratch_type_system_map.ForEach( [name, &variable_sp](TypeSystem *type_system) -> bool { @@ -2423,7 +2432,7 @@ Target::GetPersistentVariable(const ConstString &name) { return variable_sp; } -lldb::addr_t Target::GetPersistentSymbol(const ConstString &name) { +lldb::addr_t Target::GetPersistentSymbol(ConstString name) { lldb::addr_t address = LLDB_INVALID_ADDRESS; m_scratch_type_system_map.ForEach( @@ -2460,9 +2469,9 @@ lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) { } SourceManager &Target::GetSourceManager() { - if (!m_source_manager_ap) - m_source_manager_ap.reset(new SourceManager(shared_from_this())); - return *m_source_manager_ap; + if (!m_source_manager_up) + m_source_manager_up.reset(new SourceManager(shared_from_this())); + return *m_source_manager_up; } ClangModulesDeclVendor *Target::GetClangModulesDeclVendor() { @@ -2473,13 +2482,13 @@ ClangModulesDeclVendor *Target::GetClangModulesDeclVendor() { { std::lock_guard<std::mutex> guard(s_clang_modules_decl_vendor_mutex); - if (!m_clang_modules_decl_vendor_ap) { - m_clang_modules_decl_vendor_ap.reset( + if (!m_clang_modules_decl_vendor_up) { + m_clang_modules_decl_vendor_up.reset( ClangModulesDeclVendor::Create(*this)); } } - return m_clang_modules_decl_vendor_ap.get(); + return m_clang_modules_decl_vendor_up.get(); } Target::StopHookSP Target::CreateStopHook() { @@ -2546,12 +2555,14 @@ void Target::RunStopHooks() { StopHookCollection::iterator pos, end = m_stop_hooks.end(); - // If there aren't any active stop hooks, don't bother either: + // If there aren't any active stop hooks, don't bother either. + // Also see if any of the active hooks want to auto-continue. bool any_active_hooks = false; - for (pos = m_stop_hooks.begin(); pos != end; pos++) { - if ((*pos).second->IsActive()) { + bool auto_continue = false; + for (auto hook : m_stop_hooks) { + if (hook.second->IsActive()) { any_active_hooks = true; - break; + auto_continue |= hook.second->GetAutoContinue(); } } if (!any_active_hooks) @@ -2587,6 +2598,7 @@ void Target::RunStopHooks() { bool hooks_ran = false; bool print_hook_header = (m_stop_hooks.size() != 1); bool print_thread_header = (num_exe_ctx != 1); + bool did_restart = false; for (pos = m_stop_hooks.begin(); keep_going && pos != end; pos++) { // result.Clear(); @@ -2629,12 +2641,16 @@ void Target::RunStopHooks() { options.SetStopOnError(true); options.SetEchoCommands(false); options.SetPrintResults(true); + options.SetPrintErrors(true); options.SetAddToHistory(false); + // Force Async: + bool old_async = GetDebugger().GetAsyncExecution(); + GetDebugger().SetAsyncExecution(true); GetDebugger().GetCommandInterpreter().HandleCommands( cur_hook_sp->GetCommands(), &exc_ctx_with_reasons[i], options, result); - + GetDebugger().SetAsyncExecution(old_async); // If the command started the target going again, we should bag out of // running the stop hooks. if ((result.GetStatus() == eReturnStatusSuccessContinuingNoResult) || @@ -2643,13 +2659,19 @@ void Target::RunStopHooks() { StopHookCollection::iterator tmp = pos; if (++tmp != end) result.AppendMessageWithFormat("\nAborting stop hooks, hook %" PRIu64 - " set the program running.\n", + " set the program running.\n" + " Consider using '-G true' to make " + "stop hooks auto-continue.\n", cur_hook_sp->GetID()); keep_going = false; + did_restart = true; } } } } + // Finally, if auto-continue was requested, do it now: + if (!did_restart && auto_continue) + m_process_sp->PrivateResume(); result.GetImmediateOutputStream()->Flush(); result.GetImmediateErrorStream()->Flush(); @@ -2906,17 +2928,11 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { if (state == eStateStopped) { if (!launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) { if (synchronous_execution) { - error = m_process_sp->PrivateResume(); - if (error.Success()) { - state = m_process_sp->WaitForProcessToStop( - llvm::None, nullptr, true, hijack_listener_sp, stream); - const bool must_be_alive = - false; // eStateExited is ok, so this must be false - if (!StateIsStoppedState(state, must_be_alive)) { - error.SetErrorStringWithFormat("process isn't stopped: %s", - StateAsCString(state)); - } - } + // Now we have handled the stop-from-attach, and we are just switching + // to a synchronous resume. So we should switch to the SyncResume + // hijacker. + m_process_sp->RestoreProcessEvents(); + m_process_sp->ResumeSynchronous(stream); } else { m_process_sp->RestoreProcessEvents(); error = m_process_sp->PrivateResume(); @@ -3130,19 +3146,18 @@ void Target::FinalizeFileActions(ProcessLaunchInfo &info) { } } -//-------------------------------------------------------------- // Target::StopHook -//-------------------------------------------------------------- Target::StopHook::StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid) : UserID(uid), m_target_sp(target_sp), m_commands(), m_specifier_sp(), - m_thread_spec_ap(), m_active(true) {} + m_thread_spec_up() {} Target::StopHook::StopHook(const StopHook &rhs) : UserID(rhs.GetID()), m_target_sp(rhs.m_target_sp), m_commands(rhs.m_commands), m_specifier_sp(rhs.m_specifier_sp), - m_thread_spec_ap(), m_active(rhs.m_active) { - if (rhs.m_thread_spec_ap) - m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get())); + m_thread_spec_up(), m_active(rhs.m_active), + m_auto_continue(rhs.m_auto_continue) { + if (rhs.m_thread_spec_up) + m_thread_spec_up.reset(new ThreadSpec(*rhs.m_thread_spec_up)); } Target::StopHook::~StopHook() = default; @@ -3152,7 +3167,7 @@ void Target::StopHook::SetSpecifier(SymbolContextSpecifier *specifier) { } void Target::StopHook::SetThreadSpecifier(ThreadSpec *specifier) { - m_thread_spec_ap.reset(specifier); + m_thread_spec_up.reset(specifier); } void Target::StopHook::GetDescription(Stream *s, @@ -3167,6 +3182,9 @@ void Target::StopHook::GetDescription(Stream *s, else s->Indent("State: disabled\n"); + if (m_auto_continue) + s->Indent("AutoContinue on\n"); + if (m_specifier_sp) { s->Indent(); s->PutCString("Specifier:\n"); @@ -3175,10 +3193,10 @@ void Target::StopHook::GetDescription(Stream *s, s->SetIndentLevel(indent_level + 2); } - if (m_thread_spec_ap) { + if (m_thread_spec_up) { StreamString tmp; s->Indent("Thread:\n"); - m_thread_spec_ap->GetDescription(&tmp, level); + m_thread_spec_up->GetDescription(&tmp, level); s->SetIndentLevel(indent_level + 4); s->Indent(tmp.GetString()); s->PutCString("\n"); @@ -3195,9 +3213,7 @@ void Target::StopHook::GetDescription(Stream *s, s->SetIndentLevel(indent_level); } -//-------------------------------------------------------------- // class TargetProperties -//-------------------------------------------------------------- // clang-format off static constexpr OptionEnumValueElement g_dynamic_value_types[] = { @@ -3225,11 +3241,11 @@ static constexpr OptionEnumValueElement g_inline_breakpoint_enums[] = { "Always look for inline breakpoint locations when setting file and line " "breakpoints (slower but most accurate)."} }; -typedef enum x86DisassemblyFlavor { +enum x86DisassemblyFlavor { eX86DisFlavorDefault, eX86DisFlavorIntel, eX86DisFlavorATT -} x86DisassemblyFlavor; +}; static constexpr OptionEnumValueElement g_x86_dis_flavor_value_types[] = { {eX86DisFlavorDefault, "default", "Disassembler default (currently att)."}, @@ -3310,6 +3326,9 @@ static constexpr PropertyDefinition g_properties[] = { {"auto-import-clang-modules", OptionValue::eTypeBoolean, false, true, nullptr, {}, "Automatically load Clang modules referred to by the program."}, + {"import-std-module", OptionValue::eTypeBoolean, false, false, + nullptr, {}, + "Import the C++ std module to improve debugging STL containers."}, {"auto-apply-fixits", OptionValue::eTypeBoolean, false, true, nullptr, {}, "Automatically apply fix-it hints to expressions."}, {"notify-about-fixits", OptionValue::eTypeBoolean, false, true, nullptr, @@ -3448,6 +3467,7 @@ enum { ePropertyDebugFileSearchPaths, ePropertyClangModuleSearchPaths, ePropertyAutoImportClangModules, + ePropertyImportStdModule, ePropertyAutoApplyFixIts, ePropertyNotifyAboutFixIts, ePropertySaveObjects, @@ -3485,7 +3505,7 @@ enum { class TargetOptionValueProperties : public OptionValueProperties { public: - TargetOptionValueProperties(const ConstString &name) + TargetOptionValueProperties(ConstString name) : OptionValueProperties(name), m_target(nullptr), m_got_host_env(false) {} // This constructor is used when creating TargetOptionValueProperties when it @@ -3554,9 +3574,7 @@ protected: mutable bool m_got_host_env; }; -//---------------------------------------------------------------------- // TargetProperties -//---------------------------------------------------------------------- static constexpr PropertyDefinition g_experimental_properties[]{ {"inject-local-vars", OptionValue::eTypeBoolean, true, true, nullptr, {}, @@ -3582,14 +3600,12 @@ TargetExperimentalProperties::TargetExperimentalProperties() m_collection_sp->Initialize(g_experimental_properties); } -//---------------------------------------------------------------------- // TargetProperties -//---------------------------------------------------------------------- TargetProperties::TargetProperties(Target *target) : Properties(), m_launch_info() { if (target) { - m_collection_sp.reset( - new TargetOptionValueProperties(target, Target::GetGlobalProperties())); + m_collection_sp = std::make_shared<TargetOptionValueProperties>( + target, Target::GetGlobalProperties()); // Set callbacks to update launch_info whenever "settins set" updated any // of these properties @@ -3637,8 +3653,8 @@ TargetProperties::TargetProperties(Target *target) DisableASLRValueChangedCallback(this, nullptr); DisableSTDIOValueChangedCallback(this, nullptr); } else { - m_collection_sp.reset( - new TargetOptionValueProperties(ConstString("target"))); + m_collection_sp = + std::make_shared<TargetOptionValueProperties>(ConstString("target")); m_collection_sp->Initialize(g_properties); m_experimental_properties_up.reset(new TargetExperimentalProperties()); m_collection_sp->AppendProperty( @@ -3837,27 +3853,36 @@ PathMappingList &TargetProperties::GetSourcePathMap() const { return option_value->GetCurrentValue(); } -FileSpecList &TargetProperties::GetExecutableSearchPaths() { +void TargetProperties::AppendExecutableSearchPaths(const FileSpec& dir) { const uint32_t idx = ePropertyExecutableSearchPaths; OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, false, idx); assert(option_value); + option_value->AppendCurrentValue(dir); +} + +FileSpecList TargetProperties::GetExecutableSearchPaths() { + const uint32_t idx = ePropertyExecutableSearchPaths; + const OptionValueFileSpecList *option_value = + m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, + false, idx); + assert(option_value); return option_value->GetCurrentValue(); } -FileSpecList &TargetProperties::GetDebugFileSearchPaths() { +FileSpecList TargetProperties::GetDebugFileSearchPaths() { const uint32_t idx = ePropertyDebugFileSearchPaths; - OptionValueFileSpecList *option_value = + const OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, false, idx); assert(option_value); return option_value->GetCurrentValue(); } -FileSpecList &TargetProperties::GetClangModuleSearchPaths() { +FileSpecList TargetProperties::GetClangModuleSearchPaths() { const uint32_t idx = ePropertyClangModuleSearchPaths; - OptionValueFileSpecList *option_value = + const OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, false, idx); assert(option_value); @@ -3870,6 +3895,12 @@ bool TargetProperties::GetEnableAutoImportClangModules() const { nullptr, idx, g_properties[idx].default_uint_value != 0); } +bool TargetProperties::GetEnableImportStdModule() const { + const uint32_t idx = ePropertyImportStdModule; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_properties[idx].default_uint_value != 0); +} + bool TargetProperties::GetEnableAutoApplyFixIts() const { const uint32_t idx = ePropertyAutoApplyFixIts; return m_collection_sp->GetPropertyAtIndexAsBoolean( @@ -4176,9 +4207,7 @@ void TargetProperties::DisableSTDIOValueChangedCallback( this_->m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableSTDIO); } -//---------------------------------------------------------------------- // Target::TargetEventData -//---------------------------------------------------------------------- Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp) : EventData(), m_target_sp(target_sp), m_module_list() {} @@ -4189,7 +4218,7 @@ Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp, Target::TargetEventData::~TargetEventData() = default; -const ConstString &Target::TargetEventData::GetFlavorString() { +ConstString Target::TargetEventData::GetFlavorString() { static ConstString g_flavor("Target::TargetEventData"); return g_flavor; } |