diff --git a/lldb/include/lldb/Breakpoint/Breakpoint.h b/lldb/include/lldb/Breakpoint/Breakpoint.h index 04ef90c6aeac..682369f76796 100644 --- a/lldb/include/lldb/Breakpoint/Breakpoint.h +++ b/lldb/include/lldb/Breakpoint/Breakpoint.h @@ -553,10 +553,19 @@ public: /// This breakpoint's Target. //------------------------------------------------------------------ Target & - GetTarget (); + GetTarget () + { + return m_target; + } const Target & - GetTarget () const; + GetTarget () const + { + return m_target; + } + + const lldb::TargetSP + GetTargetSP (); void GetResolverDescription (Stream *s); @@ -615,6 +624,18 @@ public: return m_hardware; } + lldb::BreakpointResolverSP + GetResolver() + { + return m_resolver_sp; + } + + lldb::SearchFilterSP + GetSearchFilter() + { + return m_filter_sp; + } + protected: friend class Target; //------------------------------------------------------------------ @@ -665,6 +686,11 @@ protected: IgnoreCountShouldStop (); private: + // This one should only be used by Target to copy breakpoints from target to target - primarily from the dummy + // target to prime new targets. + Breakpoint (Target &new_target, + Breakpoint &bp_to_copy_from); + //------------------------------------------------------------------ // For Breakpoint only //------------------------------------------------------------------ diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolver.h b/lldb/include/lldb/Breakpoint/BreakpointResolver.h index 184bdc950cbc..6ba53ea92f36 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointResolver.h +++ b/lldb/include/lldb/Breakpoint/BreakpointResolver.h @@ -44,6 +44,8 @@ namespace lldb_private { class BreakpointResolver : public Searcher { +friend class Breakpoint; + public: //------------------------------------------------------------------ /// The breakpoint resolver need to have a breakpoint for "ResolveBreakpoint @@ -122,7 +124,8 @@ public: AddressResolver, // This is an instance of BreakpointResolverAddress NameResolver, // This is an instance of BreakpointResolverName FileRegexResolver, - ExceptionResolver + ExceptionResolver, + LastKnownResolverType = ExceptionResolver }; //------------------------------------------------------------------ @@ -133,6 +136,9 @@ public: return SubclassID; } + virtual lldb::BreakpointResolverSP + CopyForBreakpoint (Breakpoint &breakpoint) = 0; + protected: //------------------------------------------------------------------ /// SetSCMatchesByLine - Takes a symbol context list of matches which supposedly represent the same file and diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h b/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h index 4ca4a405957e..6c85112d2310 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h +++ b/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h @@ -62,6 +62,9 @@ public: return V->getResolverID() == BreakpointResolver::AddressResolver; } + lldb::BreakpointResolverSP + CopyForBreakpoint (Breakpoint &breakpoint) override; + protected: Address m_addr; diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h b/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h index cc1633ce1705..68ec01899321 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h +++ b/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h @@ -58,6 +58,9 @@ public: return V->getResolverID() == BreakpointResolver::FileLineResolver; } + lldb::BreakpointResolverSP + CopyForBreakpoint (Breakpoint &breakpoint) override; + protected: friend class Breakpoint; FileSpec m_file_spec; // This is the file spec we are looking for. diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverFileRegex.h b/lldb/include/lldb/Breakpoint/BreakpointResolverFileRegex.h index f1c2b1409e92..0a49833b67d1 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointResolverFileRegex.h +++ b/lldb/include/lldb/Breakpoint/BreakpointResolverFileRegex.h @@ -55,6 +55,9 @@ public: return V->getResolverID() == BreakpointResolver::FileRegexResolver; } + lldb::BreakpointResolverSP + CopyForBreakpoint (Breakpoint &breakpoint) override; + protected: friend class Breakpoint; RegularExpression m_regex; // This is the line expression that we are looking for. diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverName.h b/lldb/include/lldb/Breakpoint/BreakpointResolverName.h index f481aa9c5338..c17644784581 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointResolverName.h +++ b/lldb/include/lldb/Breakpoint/BreakpointResolverName.h @@ -85,7 +85,12 @@ public: return V->getResolverID() == BreakpointResolver::NameResolver; } + lldb::BreakpointResolverSP + CopyForBreakpoint (Breakpoint &breakpoint) override; + protected: + BreakpointResolverName(const BreakpointResolverName &rhs); + struct LookupInfo { ConstString name; @@ -113,8 +118,6 @@ protected: void AddNameLookup (const ConstString &name, uint32_t name_type_mask); -private: - DISALLOW_COPY_AND_ASSIGN(BreakpointResolverName); }; } // namespace lldb_private diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index 9a68376e23ce..15c832f4bf66 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -383,7 +383,7 @@ public: // This is for use in the command interpreter, when you either want the selected target, or if no target // is present you want to prime the dummy target with entities that will be copied over to new targets. - Target *GetSelectedOrDummyTarget(); + Target *GetSelectedOrDummyTarget(bool prefer_dummy = false); Target *GetDummyTarget(); protected: diff --git a/lldb/include/lldb/Core/SearchFilter.h b/lldb/include/lldb/Core/SearchFilter.h index 57f1b9c1a0a5..0dc3f929736a 100644 --- a/lldb/include/lldb/Core/SearchFilter.h +++ b/lldb/include/lldb/Core/SearchFilter.h @@ -225,8 +225,10 @@ public: virtual void Dump (Stream *s) const; -protected: + lldb::SearchFilterSP + CopyForBreakpoint (Breakpoint &breakpoint); +protected: // These are utility functions to assist with the search iteration. They are used by the // default Search method. @@ -248,26 +250,40 @@ protected: const SymbolContext &context, Searcher &searcher); + virtual lldb::SearchFilterSP + DoCopyForBreakpoint (Breakpoint &breakpoint) = 0; + + void + SetTarget(lldb::TargetSP &target_sp) + { + m_target_sp = target_sp; + } + lldb::TargetSP m_target_sp; // Every filter has to be associated with a target for // now since you need a starting place for the search. }; //---------------------------------------------------------------------- -/// @class SearchFilterForNonModuleSpecificSearches SearchFilter.h "lldb/Core/SearchFilter.h" -/// @brief This is a SearchFilter that searches through all modules. It also consults the Target::ModuleIsExcludedForNonModuleSpecificSearches. +/// @class SearchFilterForUnconstrainedSearches SearchFilter.h "lldb/Core/SearchFilter.h" +/// @brief This is a SearchFilter that searches through all modules. It also consults the Target::ModuleIsExcludedForUnconstrainedSearches. //---------------------------------------------------------------------- -class SearchFilterForNonModuleSpecificSearches : +class SearchFilterForUnconstrainedSearches : public SearchFilter { public: - SearchFilterForNonModuleSpecificSearches (const lldb::TargetSP &targetSP) : SearchFilter(targetSP) {} - ~SearchFilterForNonModuleSpecificSearches () {} + SearchFilterForUnconstrainedSearches (const lldb::TargetSP &target_sp) : SearchFilter(target_sp) {} + ~SearchFilterForUnconstrainedSearches () {} virtual bool ModulePasses (const FileSpec &module_spec); virtual bool ModulePasses (const lldb::ModuleSP &module_sp); + +protected: + lldb::SearchFilterSP + DoCopyForBreakpoint (Breakpoint &breakpoint) override; + }; //---------------------------------------------------------------------- @@ -328,6 +344,10 @@ public: virtual void Search (Searcher &searcher); +protected: + lldb::SearchFilterSP + DoCopyForBreakpoint (Breakpoint &breakpoint) override; + private: FileSpec m_module_spec; }; @@ -385,6 +405,10 @@ public: virtual void Search (Searcher &searcher); +protected: + lldb::SearchFilterSP + DoCopyForBreakpoint (Breakpoint &breakpoint) override; + private: FileSpecList m_module_spec_list; }; @@ -436,6 +460,10 @@ public: virtual void Search (Searcher &searcher); + +protected: + lldb::SearchFilterSP + DoCopyForBreakpoint (Breakpoint &breakpoint) override; private: FileSpecList m_module_spec_list; diff --git a/lldb/include/lldb/Interpreter/CommandObject.h b/lldb/include/lldb/Interpreter/CommandObject.h index c4105cf307f6..41c17efa4df3 100644 --- a/lldb/include/lldb/Interpreter/CommandObject.h +++ b/lldb/include/lldb/Interpreter/CommandObject.h @@ -527,7 +527,7 @@ protected: // This is for use in the command interpreter, when you either want the selected target, or if no target // is present you want to prime the dummy target with entities that will be copied over to new targets. - Target *GetSelectedOrDummyTarget(); + Target *GetSelectedOrDummyTarget(bool prefer_dummy = false); Target *GetDummyTarget(); //------------------------------------------------------------------ diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h index 6b6bd5480784..8b14cc2a0ece 100644 --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -581,7 +581,7 @@ namespace lldb_private { // The platform will return "true" from this call if the passed in module happens to be one of these. virtual bool - ModuleIsExcludedForNonModuleSpecificSearches (Target &target, const lldb::ModuleSP &module_sp) + ModuleIsExcludedForUnconstrainedSearches (Target &target, const lldb::ModuleSP &module_sp) { return false; } diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index b09e325b5cf8..a33734fd5b63 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -566,6 +566,9 @@ private: void PrimeFromDummyTarget(Target *dummy_target); + void + AddBreakpoint(lldb::BreakpointSP breakpoint_sp, bool internal); + public: ~Target(); @@ -960,9 +963,9 @@ public: //------------------------------------------------------------------ /// Return whether this FileSpec corresponds to a module that should be considered for general searches. /// - /// This API will be consulted by the SearchFilterForNonModuleSpecificSearches + /// This API will be consulted by the SearchFilterForUnconstrainedSearches /// and any module that returns \b true will not be searched. Note the - /// SearchFilterForNonModuleSpecificSearches is the search filter that + /// SearchFilterForUnconstrainedSearches is the search filter that /// gets used in the CreateBreakpoint calls when no modules is provided. /// /// The target call at present just consults the Platform's call of the @@ -974,14 +977,14 @@ public: /// @return \b true if the module should be excluded, \b false otherwise. //------------------------------------------------------------------ bool - ModuleIsExcludedForNonModuleSpecificSearches (const FileSpec &module_spec); + ModuleIsExcludedForUnconstrainedSearches (const FileSpec &module_spec); //------------------------------------------------------------------ /// Return whether this module should be considered for general searches. /// - /// This API will be consulted by the SearchFilterForNonModuleSpecificSearches + /// This API will be consulted by the SearchFilterForUnconstrainedSearches /// and any module that returns \b true will not be searched. Note the - /// SearchFilterForNonModuleSpecificSearches is the search filter that + /// SearchFilterForUnconstrainedSearches is the search filter that /// gets used in the CreateBreakpoint calls when no modules is provided. /// /// The target call at present just consults the Platform's call of the @@ -996,7 +999,7 @@ public: /// @return \b true if the module should be excluded, \b false otherwise. //------------------------------------------------------------------ bool - ModuleIsExcludedForNonModuleSpecificSearches (const lldb::ModuleSP &module_sp); + ModuleIsExcludedForUnconstrainedSearches (const lldb::ModuleSP &module_sp); ArchSpec & GetArchitecture () diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp index 7f4faaeccf26..1a3a6b552ab2 100644 --- a/lldb/source/Breakpoint/Breakpoint.cpp +++ b/lldb/source/Breakpoint/Breakpoint.cpp @@ -65,6 +65,19 @@ Breakpoint::Breakpoint(Target &target, m_being_created = false; } +Breakpoint::Breakpoint (Target &new_target, Breakpoint &source_bp) : + m_being_created(true), + m_hardware(source_bp.m_hardware), + m_target(new_target), + m_options (source_bp.m_options), + m_locations(*this), + m_resolve_indirect_symbols(source_bp.m_resolve_indirect_symbols) +{ + // Now go through and copy the filter & resolver: + m_resolver_sp = source_bp.m_resolver_sp->CopyForBreakpoint(*this); + m_filter_sp = source_bp.m_filter_sp->CopyForBreakpoint(*this); +} + //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- @@ -72,26 +85,18 @@ Breakpoint::~Breakpoint() { } +const lldb::TargetSP +Breakpoint::GetTargetSP () +{ + return m_target.shared_from_this(); +} + bool Breakpoint::IsInternal () const { return LLDB_BREAK_ID_IS_INTERNAL(m_bid); } - - -Target& -Breakpoint::GetTarget () -{ - return m_target; -} - -const Target& -Breakpoint::GetTarget () const -{ - return m_target; -} - BreakpointLocationSP Breakpoint::AddLocation (const Address &addr, bool *new_location) { diff --git a/lldb/source/Breakpoint/BreakpointResolverAddress.cpp b/lldb/source/Breakpoint/BreakpointResolverAddress.cpp index 1bcef93aedad..d6647130c54c 100644 --- a/lldb/source/Breakpoint/BreakpointResolverAddress.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverAddress.cpp @@ -109,3 +109,11 @@ BreakpointResolverAddress::Dump (Stream *s) const { } + +lldb::BreakpointResolverSP +BreakpointResolverAddress::CopyForBreakpoint (Breakpoint &breakpoint) +{ + lldb::BreakpointResolverSP ret_sp(new BreakpointResolverAddress(&breakpoint, m_addr)); + return ret_sp; +} + diff --git a/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp b/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp index dcee2fd54125..950054c3d720 100644 --- a/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp @@ -110,3 +110,14 @@ BreakpointResolverFileLine::Dump (Stream *s) const } +lldb::BreakpointResolverSP +BreakpointResolverFileLine::CopyForBreakpoint (Breakpoint &breakpoint) +{ + lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileLine(&breakpoint, + m_file_spec, + m_line_number, + m_inlines, + m_skip_prologue)); + + return ret_sp; +} diff --git a/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp b/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp index 01aecee7b9c2..c71d9bf5ba8c 100644 --- a/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp @@ -95,3 +95,10 @@ BreakpointResolverFileRegex::Dump (Stream *s) const } +lldb::BreakpointResolverSP +BreakpointResolverFileRegex::CopyForBreakpoint (Breakpoint &breakpoint) +{ + lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileRegex(&breakpoint, m_regex)); + return ret_sp; +} + diff --git a/lldb/source/Breakpoint/BreakpointResolverName.cpp b/lldb/source/Breakpoint/BreakpointResolverName.cpp index 3ac3ed06fc70..581f7b016173 100644 --- a/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -121,6 +121,17 @@ BreakpointResolverName::~BreakpointResolverName () { } +BreakpointResolverName::BreakpointResolverName(const BreakpointResolverName &rhs) : + BreakpointResolver(rhs.m_breakpoint, BreakpointResolver::NameResolver), + m_lookups(rhs.m_lookups), + m_class_name(rhs.m_class_name), + m_regex(rhs.m_regex), + m_match_type (rhs.m_match_type), + m_skip_prologue (rhs.m_skip_prologue) +{ + +} + void BreakpointResolverName::AddNameLookup (const ConstString &name, uint32_t name_type_mask) { @@ -371,3 +382,10 @@ BreakpointResolverName::Dump (Stream *s) const } +lldb::BreakpointResolverSP +BreakpointResolverName::CopyForBreakpoint (Breakpoint &breakpoint) +{ + lldb::BreakpointResolverSP ret_sp(new BreakpointResolverName(*this)); + ret_sp->SetBreakpoint(&breakpoint); + return ret_sp; +} diff --git a/lldb/source/Commands/CommandCompletions.cpp b/lldb/source/Commands/CommandCompletions.cpp index f0ad4a896739..c65dd9d460f4 100644 --- a/lldb/source/Commands/CommandCompletions.cpp +++ b/lldb/source/Commands/CommandCompletions.cpp @@ -112,7 +112,7 @@ CommandCompletions::SourceFiles if (searcher == NULL) { lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); - SearchFilter null_searcher (target_sp); + SearchFilterForUnconstrainedSearches null_searcher (target_sp); completer.DoCompletion (&null_searcher); } else @@ -375,7 +375,7 @@ CommandCompletions::Modules if (searcher == NULL) { lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); - SearchFilter null_searcher (target_sp); + SearchFilterForUnconstrainedSearches null_searcher (target_sp); completer.DoCompletion (&null_searcher); } else @@ -406,7 +406,7 @@ CommandCompletions::Symbols if (searcher == NULL) { lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); - SearchFilter null_searcher (target_sp); + SearchFilterForUnconstrainedSearches null_searcher (target_sp); completer.DoCompletion (&null_searcher); } else diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp index fb8a1814c648..69aa8bf6a48e 100644 --- a/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -145,6 +145,10 @@ public: m_condition.assign(option_arg); break; + case 'D': + m_use_dummy = true; + break; + case 'E': { LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg); @@ -324,6 +328,7 @@ public: m_language = eLanguageTypeUnknown; m_skip_prologue = eLazyBoolCalculate; m_one_shot = false; + m_use_dummy = false; } const OptionDefinition* @@ -359,15 +364,17 @@ public: lldb::LanguageType m_language; LazyBool m_skip_prologue; bool m_one_shot; + bool m_use_dummy; }; protected: virtual bool DoExecute (Args& command, - CommandReturnObject &result) + CommandReturnObject &result) { - Target *target = GetSelectedOrDummyTarget(); + Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); + if (target == nullptr) { result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command)."); @@ -709,6 +716,9 @@ CommandObjectBreakpointSet::CommandOptions::g_option_table[] = { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." }, + { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, + "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -766,7 +776,8 @@ public: m_name_passed (false), m_queue_passed (false), m_condition_passed (false), - m_one_shot_passed (false) + m_one_shot_passed (false), + m_use_dummy (false) { } @@ -792,6 +803,9 @@ public: m_enable_passed = true; m_enable_value = false; break; + case 'D': + m_use_dummy = true; + break; case 'e': m_enable_passed = true; m_enable_value = true; @@ -888,6 +902,7 @@ public: m_name_passed = false; m_condition_passed = false; m_one_shot_passed = false; + m_use_dummy = false; } const OptionDefinition* @@ -918,6 +933,7 @@ public: bool m_queue_passed; bool m_condition_passed; bool m_one_shot_passed; + bool m_use_dummy; }; @@ -925,7 +941,7 @@ protected: virtual bool DoExecute (Args& command, CommandReturnObject &result) { - Target *target = GetSelectedOrDummyTarget(); + Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); if (target == NULL) { result.AppendError ("Invalid target. No existing target or breakpoints."); @@ -1024,6 +1040,8 @@ CommandObjectBreakpointModify::CommandOptions::g_option_table[] = { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."}, { LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."}, { LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."}, +{ LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, + { 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -1293,7 +1311,8 @@ public: CommandOptions (CommandInterpreter &interpreter) : Options (interpreter), - m_level (lldb::eDescriptionLevelBrief) // Breakpoint List defaults to brief descriptions + m_level (lldb::eDescriptionLevelBrief), + m_use_dummy(false) { } @@ -1311,6 +1330,9 @@ public: case 'b': m_level = lldb::eDescriptionLevelBrief; break; + case 'D': + m_use_dummy = true; + break; case 'f': m_level = lldb::eDescriptionLevelFull; break; @@ -1333,6 +1355,7 @@ public: { m_level = lldb::eDescriptionLevelFull; m_internal = false; + m_use_dummy = false; } const OptionDefinition * @@ -1350,13 +1373,15 @@ public: lldb::DescriptionLevel m_level; bool m_internal; + bool m_use_dummy; }; protected: virtual bool DoExecute (Args& command, CommandReturnObject &result) { - Target *target = GetSelectedOrDummyTarget(); + Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); + if (target == NULL) { result.AppendError ("Invalid target. No current target or breakpoints."); @@ -1438,6 +1463,9 @@ CommandObjectBreakpointList::CommandOptions::g_option_table[] = { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Explain everything we know about the breakpoint (for debugging debugger bugs)." }, + { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, + "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -1656,7 +1684,8 @@ public: CommandObjectParsed (interpreter, "breakpoint delete", "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.", - NULL) + NULL), + m_options (interpreter) { CommandArgumentEntry arg; CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange); @@ -1667,11 +1696,78 @@ public: virtual ~CommandObjectBreakpointDelete () {} + virtual Options * + GetOptions () + { + return &m_options; + } + + class CommandOptions : public Options + { + public: + + CommandOptions (CommandInterpreter &interpreter) : + Options (interpreter), + m_use_dummy (false), + m_force (false) + { + } + + virtual + ~CommandOptions () {} + + virtual Error + SetOptionValue (uint32_t option_idx, const char *option_arg) + { + Error error; + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) + { + case 'f': + m_force = true; + break; + + case 'D': + m_use_dummy = true; + break; + + default: + error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); + break; + } + + return error; + } + + void + OptionParsingStarting () + { + m_use_dummy = false; + m_force = false; + } + + const OptionDefinition* + GetDefinitions () + { + return g_option_table; + } + + // Options table: Required for subclasses of Options. + + static OptionDefinition g_option_table[]; + + // Instance variables to hold the values for command options. + bool m_use_dummy; + bool m_force; + }; + protected: virtual bool DoExecute (Args& command, CommandReturnObject &result) { - Target *target = GetSelectedOrDummyTarget(); + Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); + if (target == NULL) { result.AppendError ("Invalid target. No existing target or breakpoints."); @@ -1695,7 +1791,7 @@ protected: if (command.GetArgumentCount() == 0) { - if (!m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true)) + if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true)) { result.AppendMessage("Operation cancelled..."); } @@ -1748,6 +1844,20 @@ protected: } return result.Succeeded(); } +private: + CommandOptions m_options; +}; + +OptionDefinition +CommandObjectBreakpointDelete::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, + "Delete all breakpoints without querying for confirmation."}, + + { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, + "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, + + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- diff --git a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp index 955c26f99d31..ded03c532ce5 100644 --- a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp @@ -389,6 +389,10 @@ one command per line.\n" ); } break; + case 'D': + m_use_dummy = true; + break; + default: break; } @@ -405,6 +409,7 @@ one command per line.\n" ); m_stop_on_error = true; m_one_liner.clear(); m_function_name.clear(); + m_use_dummy = false; } const OptionDefinition* @@ -428,13 +433,14 @@ one command per line.\n" ); std::string m_one_liner; bool m_stop_on_error; std::string m_function_name; + bool m_use_dummy; }; protected: virtual bool DoExecute (Args& command, CommandReturnObject &result) { - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); if (target == NULL) { @@ -580,6 +586,9 @@ CommandObjectBreakpointCommandAdd::CommandOptions::g_option_table[] = { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Give the name of a Python function to run as command for this breakpoint. Be sure to give a module name if appropriate."}, + { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, + "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -594,7 +603,8 @@ public: CommandObjectParsed (interpreter, "delete", "Delete the set of commands from a breakpoint.", - NULL) + NULL), + m_options (interpreter) { CommandArgumentEntry arg; CommandArgumentData bp_id_arg; @@ -614,11 +624,70 @@ public: virtual ~CommandObjectBreakpointCommandDelete () {} + virtual Options * + GetOptions () + { + return &m_options; + } + + class CommandOptions : public Options + { + public: + + CommandOptions (CommandInterpreter &interpreter) : + Options (interpreter), + m_use_dummy (false) + { + } + + virtual + ~CommandOptions () {} + + virtual Error + SetOptionValue (uint32_t option_idx, const char *option_arg) + { + Error error; + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) + { + case 'D': + m_use_dummy = true; + break; + + default: + error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); + break; + } + + return error; + } + + void + OptionParsingStarting () + { + m_use_dummy = false; + } + + const OptionDefinition* + GetDefinitions () + { + return g_option_table; + } + + // Options table: Required for subclasses of Options. + + static OptionDefinition g_option_table[]; + + // Instance variables to hold the values for command options. + bool m_use_dummy; + }; + protected: virtual bool DoExecute (Args& command, CommandReturnObject &result) { - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); if (target == NULL) { @@ -679,8 +748,20 @@ protected: } return result.Succeeded(); } +private: + CommandOptions m_options; }; +OptionDefinition +CommandObjectBreakpointCommandDelete::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, + "Delete commands from Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, + + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } +}; + + //------------------------------------------------------------------------- // CommandObjectBreakpointCommandList //------------------------------------------------------------------------- diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp index f8a5c42161f5..8fb03e69ac42 100644 --- a/lldb/source/Commands/CommandObjectSource.cpp +++ b/lldb/source/Commands/CommandObjectSource.cpp @@ -421,7 +421,7 @@ protected: { const bool show_inlines = true; m_breakpoint_locations.Reset (start_file, 0, show_inlines); - SearchFilter target_search_filter (m_exe_ctx.GetTargetSP()); + SearchFilterForUnconstrainedSearches target_search_filter (m_exe_ctx.GetTargetSP()); target_search_filter.Search (m_breakpoint_locations); } @@ -682,7 +682,7 @@ protected: m_breakpoint_locations.Clear(); const bool show_inlines = true; m_breakpoint_locations.Reset (*sc.comp_unit, 0, show_inlines); - SearchFilter target_search_filter (target->shared_from_this()); + SearchFilterForUnconstrainedSearches target_search_filter (target->shared_from_this()); target_search_filter.Search (m_breakpoint_locations); } @@ -743,7 +743,7 @@ protected: { const bool show_inlines = true; m_breakpoint_locations.Reset (last_file_sp->GetFileSpec(), 0, show_inlines); - SearchFilter target_search_filter (target->shared_from_this()); + SearchFilterForUnconstrainedSearches target_search_filter (target->shared_from_this()); target_search_filter.Search (m_breakpoint_locations); } } @@ -846,7 +846,7 @@ protected: { const bool show_inlines = true; m_breakpoint_locations.Reset (*sc.comp_unit, 0, show_inlines); - SearchFilter target_search_filter (target->shared_from_this()); + SearchFilterForUnconstrainedSearches target_search_filter (target->shared_from_this()); target_search_filter.Search (m_breakpoint_locations); } else diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 3462fcdaf264..c7342ade6cad 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -3418,12 +3418,16 @@ Debugger::GetDummyTarget() } Target * -Debugger::GetSelectedOrDummyTarget() +Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) { - Target *return_target = m_target_list.GetSelectedTarget().get(); - if (return_target) - return return_target; - + Target *target = nullptr; + if (!prefer_dummy) + { + target = m_target_list.GetSelectedTarget().get(); + if (target) + return target; + } + return GetDummyTarget(); } diff --git a/lldb/source/Core/SearchFilter.cpp b/lldb/source/Core/SearchFilter.cpp index dee2f2e4bd5e..8e3d8d0a91eb 100644 --- a/lldb/source/Core/SearchFilter.cpp +++ b/lldb/source/Core/SearchFilter.cpp @@ -119,6 +119,15 @@ SearchFilter::Dump (Stream *s) const } +lldb::SearchFilterSP +SearchFilter::CopyForBreakpoint (Breakpoint &breakpoint) +{ + SearchFilterSP ret_sp = DoCopyForBreakpoint (breakpoint); + TargetSP target_sp = breakpoint.GetTargetSP(); + ret_sp->SetTarget(target_sp); + return ret_sp; +} + //---------------------------------------------------------------------- // UTILITY Functions to help iterate down through the elements of the // SymbolContext. @@ -281,29 +290,36 @@ SearchFilter::DoFunctionIteration (Function *function, const SymbolContext &cont } //---------------------------------------------------------------------- -// SearchFilterForNonModuleSpecificSearches: +// SearchFilterForUnconstrainedSearches: // Selects a shared library matching a given file spec, consulting the targets "black list". //---------------------------------------------------------------------- - bool - SearchFilterForNonModuleSpecificSearches::ModulePasses (const FileSpec &module_spec) - { - if (m_target_sp->ModuleIsExcludedForNonModuleSpecificSearches (module_spec)) - return false; - else - return true; - } - - bool - SearchFilterForNonModuleSpecificSearches::ModulePasses (const lldb::ModuleSP &module_sp) - { - if (!module_sp) - return true; - else if (m_target_sp->ModuleIsExcludedForNonModuleSpecificSearches (module_sp)) - return false; - else - return true; - } +bool +SearchFilterForUnconstrainedSearches::ModulePasses (const FileSpec &module_spec) +{ + if (m_target_sp->ModuleIsExcludedForUnconstrainedSearches (module_spec)) + return false; + else + return true; +} + +bool +SearchFilterForUnconstrainedSearches::ModulePasses (const lldb::ModuleSP &module_sp) +{ + if (!module_sp) + return true; + else if (m_target_sp->ModuleIsExcludedForUnconstrainedSearches (module_sp)) + return false; + else + return true; +} + +lldb::SearchFilterSP +SearchFilterForUnconstrainedSearches::DoCopyForBreakpoint (Breakpoint &breakpoint) +{ + SearchFilterSP ret_sp(new SearchFilterForUnconstrainedSearches(*this)); + return ret_sp; +} //---------------------------------------------------------------------- // SearchFilterByModule: @@ -449,6 +465,14 @@ SearchFilterByModule::Dump (Stream *s) const { } + +lldb::SearchFilterSP +SearchFilterByModule::DoCopyForBreakpoint (Breakpoint &breakpoint) +{ + SearchFilterSP ret_sp(new SearchFilterByModule(*this)); + return ret_sp; +} + //---------------------------------------------------------------------- // SearchFilterByModuleList: // Selects a shared library matching a given file spec @@ -458,7 +482,8 @@ SearchFilterByModule::Dump (Stream *s) const // SearchFilterByModuleList constructors //---------------------------------------------------------------------- -SearchFilterByModuleList::SearchFilterByModuleList (const lldb::TargetSP &target_sp, const FileSpecList &module_list) : +SearchFilterByModuleList::SearchFilterByModuleList (const lldb::TargetSP &target_sp, + const FileSpecList &module_list) : SearchFilter (target_sp), m_module_spec_list (module_list) { @@ -623,6 +648,14 @@ SearchFilterByModuleList::Dump (Stream *s) const } +lldb::SearchFilterSP +SearchFilterByModuleList::DoCopyForBreakpoint (Breakpoint &breakpoint) +{ + SearchFilterSP ret_sp(new SearchFilterByModuleList(*this)); + return ret_sp; +} + + //---------------------------------------------------------------------- // SearchFilterByModuleListAndCU: // Selects a shared library matching a given file spec @@ -814,3 +847,10 @@ SearchFilterByModuleListAndCU::Dump (Stream *s) const } +lldb::SearchFilterSP +SearchFilterByModuleListAndCU::DoCopyForBreakpoint (Breakpoint &breakpoint) +{ + SearchFilterSP ret_sp(new SearchFilterByModuleListAndCU(*this)); + return ret_sp; +} + diff --git a/lldb/source/Interpreter/CommandObject.cpp b/lldb/source/Interpreter/CommandObject.cpp index 7375b43baac8..0096541d7410 100644 --- a/lldb/source/Interpreter/CommandObject.cpp +++ b/lldb/source/Interpreter/CommandObject.cpp @@ -1025,9 +1025,9 @@ CommandObject::GetDummyTarget() } Target * -CommandObject::GetSelectedOrDummyTarget() +CommandObject::GetSelectedOrDummyTarget(bool prefer_dummy) { - return m_interpreter.GetDebugger().GetSelectedOrDummyTarget(); + return m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy); } bool diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index b86909fabadc..cf1d1529f2e2 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -666,7 +666,7 @@ PlatformDarwin::FindProcesses (const ProcessInstanceInfoMatch &match_info, } bool -PlatformDarwin::ModuleIsExcludedForNonModuleSpecificSearches (lldb_private::Target &target, const lldb::ModuleSP &module_sp) +PlatformDarwin::ModuleIsExcludedForUnconstrainedSearches (lldb_private::Target &target, const lldb::ModuleSP &module_sp) { if (!module_sp) return false; diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h index ca19d264069c..980d8a8d2802 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h @@ -66,7 +66,7 @@ public: lldb_private::ProcessInstanceInfoList &process_infos) override; bool - ModuleIsExcludedForNonModuleSpecificSearches(lldb_private::Target &target, + ModuleIsExcludedForUnconstrainedSearches(lldb_private::Target &target, const lldb::ModuleSP &module_sp) override; bool diff --git a/lldb/source/Target/LanguageRuntime.cpp b/lldb/source/Target/LanguageRuntime.cpp index 9d48d8b2de7f..32faa1788f88 100644 --- a/lldb/source/Target/LanguageRuntime.cpp +++ b/lldb/source/Target/LanguageRuntime.cpp @@ -10,6 +10,7 @@ #include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/Target.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/SearchFilter.h" using namespace lldb; using namespace lldb_private; @@ -19,15 +20,20 @@ class ExceptionSearchFilter : public SearchFilter { public: ExceptionSearchFilter (const lldb::TargetSP &target_sp, - lldb::LanguageType language) : + lldb::LanguageType language, + bool update_module_list = true) : SearchFilter (target_sp), m_language (language), m_language_runtime (NULL), m_filter_sp () { - UpdateModuleListIfNeeded (); + if (update_module_list) + UpdateModuleListIfNeeded (); } - + + virtual + ~ExceptionSearchFilter() {}; + virtual bool ModulePasses (const lldb::ModuleSP &module_sp) { @@ -68,6 +74,12 @@ protected: LanguageRuntime *m_language_runtime; SearchFilterSP m_filter_sp; + SearchFilterSP + DoCopyForBreakpoint(Breakpoint &breakpoint) override + { + return SearchFilterSP(new ExceptionSearchFilter(TargetSP(), m_language, false)); + } + void UpdateModuleListIfNeeded () { @@ -174,6 +186,12 @@ public: return V->getResolverID() == BreakpointResolver::ExceptionResolver; } protected: + BreakpointResolverSP + CopyForBreakpoint (Breakpoint &breakpoint) override + { + return BreakpointResolverSP(new ExceptionBreakpointResolver(m_language, m_catch_bp, m_throw_bp)); + } + bool SetActualResolver() { diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 02125f9c0625..76a89a451873 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -100,9 +100,6 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::Plat CheckInWithManager(); - if (!m_is_dummy_target) - PrimeFromDummyTarget(m_debugger.GetDummyTarget()); - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); if (log) log->Printf ("%p Target::Target()", static_cast(this)); @@ -119,7 +116,15 @@ Target::PrimeFromDummyTarget(Target *target) return; m_stop_hooks = target->m_stop_hooks; - + + for (BreakpointSP breakpoint_sp : target->m_breakpoint_list.Breakpoints()) + { + if (breakpoint_sp->IsInternal()) + continue; + + BreakpointSP new_bp (new Breakpoint (*this, *breakpoint_sp.get())); + AddBreakpoint (new_bp, false); + } } //---------------------------------------------------------------------- @@ -346,7 +351,7 @@ Target::CreateBreakpoint (lldb::addr_t addr, bool internal, bool hardware) BreakpointSP Target::CreateBreakpoint (Address &addr, bool internal, bool hardware) { - SearchFilterSP filter_sp(new SearchFilterForNonModuleSpecificSearches (shared_from_this())); + SearchFilterSP filter_sp(new SearchFilterForUnconstrainedSearches (shared_from_this())); BreakpointResolverSP resolver_sp (new BreakpointResolverAddress (NULL, addr)); return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, false); } @@ -446,7 +451,7 @@ Target::GetSearchFilterForModule (const FileSpec *containingModule) else { if (m_search_filter_sp.get() == NULL) - m_search_filter_sp.reset (new SearchFilterForNonModuleSpecificSearches (shared_from_this())); + m_search_filter_sp.reset (new SearchFilterForUnconstrainedSearches (shared_from_this())); filter_sp = m_search_filter_sp; } return filter_sp; @@ -465,7 +470,7 @@ Target::GetSearchFilterForModuleList (const FileSpecList *containingModules) else { if (m_search_filter_sp.get() == NULL) - m_search_filter_sp.reset (new SearchFilterForNonModuleSpecificSearches (shared_from_this())); + m_search_filter_sp.reset (new SearchFilterForUnconstrainedSearches (shared_from_this())); filter_sp = m_search_filter_sp; } return filter_sp; @@ -526,29 +531,35 @@ Target::CreateBreakpoint (SearchFilterSP &filter_sp, BreakpointResolverSP &resol { bp_sp.reset(new Breakpoint (*this, filter_sp, resolver_sp, request_hardware, resolve_indirect_symbols)); resolver_sp->SetBreakpoint (bp_sp.get()); - - if (internal) - m_internal_breakpoint_list.Add (bp_sp, false); - else - m_breakpoint_list.Add (bp_sp, true); - - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); - if (log) - { - StreamString s; - bp_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); - log->Printf ("Target::%s (internal = %s) => break_id = %s\n", __FUNCTION__, internal ? "yes" : "no", s.GetData()); - } - - bp_sp->ResolveBreakpoint(); + AddBreakpoint (bp_sp, internal); } - - if (!internal && bp_sp) + return bp_sp; +} + +void +Target::AddBreakpoint (lldb::BreakpointSP bp_sp, bool internal) +{ + if (!bp_sp) + return; + if (internal) + m_internal_breakpoint_list.Add (bp_sp, false); + else + m_breakpoint_list.Add (bp_sp, true); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); + if (log) + { + StreamString s; + bp_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); + log->Printf ("Target::%s (internal = %s) => break_id = %s\n", __FUNCTION__, bp_sp->IsInternal() ? "yes" : "no", s.GetData()); + } + + bp_sp->ResolveBreakpoint(); + + if (!internal) { m_last_created_breakpoint = bp_sp; } - - return bp_sp; } bool @@ -1238,7 +1249,7 @@ Target::ModulesDidUnload (ModuleList &module_list, bool delete_locations) } bool -Target::ModuleIsExcludedForNonModuleSpecificSearches (const FileSpec &module_file_spec) +Target::ModuleIsExcludedForUnconstrainedSearches (const FileSpec &module_file_spec) { if (GetBreakpointsConsultPlatformAvoidList()) { @@ -1252,7 +1263,7 @@ Target::ModuleIsExcludedForNonModuleSpecificSearches (const FileSpec &module_fil { for (size_t i = 0; i < num_modules; i++) { - if (!ModuleIsExcludedForNonModuleSpecificSearches (matchingModules.GetModuleAtIndex(i))) + if (!ModuleIsExcludedForUnconstrainedSearches (matchingModules.GetModuleAtIndex(i))) return false; } return true; @@ -1262,12 +1273,12 @@ Target::ModuleIsExcludedForNonModuleSpecificSearches (const FileSpec &module_fil } bool -Target::ModuleIsExcludedForNonModuleSpecificSearches (const lldb::ModuleSP &module_sp) +Target::ModuleIsExcludedForUnconstrainedSearches (const lldb::ModuleSP &module_sp) { if (GetBreakpointsConsultPlatformAvoidList()) { if (m_platform_sp) - return m_platform_sp->ModuleIsExcludedForNonModuleSpecificSearches (*this, module_sp); + return m_platform_sp->ModuleIsExcludedForUnconstrainedSearches (*this, module_sp); } return false; } diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp index 741ed9b6d884..28ad47e3d81d 100644 --- a/lldb/source/Target/TargetList.cpp +++ b/lldb/source/Target/TargetList.cpp @@ -501,6 +501,8 @@ TargetList::CreateTargetInternal (Debugger &debugger, Mutex::Locker locker(m_target_list_mutex); m_selected_target_idx = m_target_list.size(); m_target_list.push_back(target_sp); + // Now prime this from the dummy target: + target_sp->PrimeFromDummyTarget(debugger.GetDummyTarget()); } else {