diff options
author | Ed Maste <emaste@FreeBSD.org> | 2015-02-06 21:38:51 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2015-02-06 21:38:51 +0000 |
commit | 205afe679855a4ce8149cdaa94d3f0868ce796dc (patch) | |
tree | 09bc83f73246ee3c7a779605cd0122093d2a8a19 /source/Breakpoint | |
parent | 0cac4ca3916ac24ab6139d03cbfd18db9e715bfe (diff) |
Diffstat (limited to 'source/Breakpoint')
-rw-r--r-- | source/Breakpoint/Breakpoint.cpp | 398 | ||||
-rw-r--r-- | source/Breakpoint/BreakpointID.cpp | 17 | ||||
-rw-r--r-- | source/Breakpoint/BreakpointIDList.cpp | 44 | ||||
-rw-r--r-- | source/Breakpoint/BreakpointLocation.cpp | 23 | ||||
-rw-r--r-- | source/Breakpoint/BreakpointLocationCollection.cpp | 1 | ||||
-rw-r--r-- | source/Breakpoint/BreakpointLocationList.cpp | 27 | ||||
-rw-r--r-- | source/Breakpoint/BreakpointOptions.cpp | 3 | ||||
-rw-r--r-- | source/Breakpoint/BreakpointResolverAddress.cpp | 8 | ||||
-rw-r--r-- | source/Breakpoint/BreakpointResolverFileLine.cpp | 11 | ||||
-rw-r--r-- | source/Breakpoint/BreakpointResolverFileRegex.cpp | 7 | ||||
-rw-r--r-- | source/Breakpoint/BreakpointResolverName.cpp | 18 | ||||
-rw-r--r-- | source/Breakpoint/BreakpointSite.cpp | 9 |
12 files changed, 500 insertions, 66 deletions
diff --git a/source/Breakpoint/Breakpoint.cpp b/source/Breakpoint/Breakpoint.cpp index 7d08170e4aed..bc269cdb95ac 100644 --- a/source/Breakpoint/Breakpoint.cpp +++ b/source/Breakpoint/Breakpoint.cpp @@ -20,11 +20,14 @@ #include "lldb/Breakpoint/BreakpointResolver.h" #include "lldb/Breakpoint/BreakpointResolverFileLine.h" #include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/SearchFilter.h" #include "lldb/Core/Section.h" #include "lldb/Core/Stream.h" #include "lldb/Core/StreamString.h" +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/Function.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadSpec.h" @@ -62,6 +65,20 @@ 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_name_list (source_bp.m_name_list), + 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 //---------------------------------------------------------------------- @@ -69,24 +86,16 @@ Breakpoint::~Breakpoint() { } -bool -Breakpoint::IsInternal () const -{ - return LLDB_BREAK_ID_IS_INTERNAL(m_bid); -} - - - -Target& -Breakpoint::GetTarget () +const lldb::TargetSP +Breakpoint::GetTargetSP () { - return m_target; + return m_target.shared_from_this(); } -const Target& -Breakpoint::GetTarget () const +bool +Breakpoint::IsInternal () const { - return m_target; + return LLDB_BREAK_ID_IS_INTERNAL(m_bid); } BreakpointLocationSP @@ -349,10 +358,41 @@ Breakpoint::ResolveBreakpoint () } void -Breakpoint::ResolveBreakpointInModules (ModuleList &module_list) +Breakpoint::ResolveBreakpointInModules (ModuleList &module_list, BreakpointLocationCollection &new_locations) +{ + m_locations.StartRecordingNewLocations(new_locations); + + m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list); + + m_locations.StopRecordingNewLocations(); +} + +void +Breakpoint::ResolveBreakpointInModules (ModuleList &module_list, bool send_event) { if (m_resolver_sp) - m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list); + { + // If this is not an internal breakpoint, set up to record the new locations, then dispatch + // an event with the new locations. + if (!IsInternal() && send_event) + { + BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded, + shared_from_this()); + + ResolveBreakpointInModules (module_list, new_locations_event->GetBreakpointLocationCollection()); + + if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0) + { + SendBreakpointChangedEvent (new_locations_event); + } + else + delete new_locations_event; + } + else + { + m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list); + } + } } void @@ -368,6 +408,11 @@ Breakpoint::ClearAllBreakpointSites () void Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_locations) { + Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); + if (log) + log->Printf ("Breakpoint::ModulesChanged: num_modules: %zu load: %i delete_locations: %i\n", + module_list.GetSize(), load, delete_locations); + Mutex::Locker modules_mutex(module_list.GetMutex()); if (load) { @@ -383,32 +428,27 @@ Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_loca // them after the locations pass. Have to do it this way because // resolving breakpoints will add new locations potentially. - const size_t num_locs = m_locations.GetSize(); - size_t num_modules = module_list.GetSize(); - for (size_t i = 0; i < num_modules; i++) + for (ModuleSP module_sp : module_list.ModulesNoLocking()) { bool seen = false; - ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i)); if (!m_filter_sp->ModulePasses (module_sp)) continue; - for (size_t loc_idx = 0; loc_idx < num_locs; loc_idx++) + for (BreakpointLocationSP break_loc_sp : m_locations.BreakpointLocations()) { - BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx); - if (!break_loc->IsEnabled()) + if (!break_loc_sp->IsEnabled()) continue; - SectionSP section_sp (break_loc->GetAddress().GetSection()); + SectionSP section_sp (break_loc_sp->GetAddress().GetSection()); if (!section_sp || section_sp->GetModule() == module_sp) { if (!seen) seen = true; - if (!break_loc->ResolveBreakpointSite()) + if (!break_loc_sp->ResolveBreakpointSite()) { - Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); if (log) log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n", - break_loc->GetID(), GetID()); + break_loc_sp->GetID(), GetID()); } } } @@ -420,28 +460,7 @@ Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_loca if (new_modules.GetSize() > 0) { - // If this is not an internal breakpoint, set up to record the new locations, then dispatch - // an event with the new locations. - if (!IsInternal()) - { - BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded, - shared_from_this()); - - m_locations.StartRecordingNewLocations(new_locations_event->GetBreakpointLocationCollection()); - - ResolveBreakpointInModules(new_modules); - - m_locations.StopRecordingNewLocations(); - if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0) - { - SendBreakpointChangedEvent (new_locations_event); - } - else - delete new_locations_event; - } - else - ResolveBreakpointInModules(new_modules); - + ResolveBreakpointInModules(new_modules); } } else @@ -498,21 +517,251 @@ Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_loca } } +namespace +{ +static bool +SymbolContextsMightBeEquivalent(SymbolContext &old_sc, SymbolContext &new_sc) +{ + bool equivalent_scs = false; + + if (old_sc.module_sp.get() == new_sc.module_sp.get()) + { + // If these come from the same module, we can directly compare the pointers: + if (old_sc.comp_unit && new_sc.comp_unit + && (old_sc.comp_unit == new_sc.comp_unit)) + { + if (old_sc.function && new_sc.function + && (old_sc.function == new_sc.function)) + { + equivalent_scs = true; + } + } + else if (old_sc.symbol && new_sc.symbol + && (old_sc.symbol == new_sc.symbol)) + { + equivalent_scs = true; + } + } + else + { + // Otherwise we will compare by name... + if (old_sc.comp_unit && new_sc.comp_unit) + { + if (FileSpec::Equal(*old_sc.comp_unit, *new_sc.comp_unit, true)) + { + // Now check the functions: + if (old_sc.function && new_sc.function + && (old_sc.function->GetName() == new_sc.function->GetName())) + { + equivalent_scs = true; + } + } + } + else if (old_sc.symbol && new_sc.symbol) + { + if (Mangled::Compare(old_sc.symbol->GetMangled(), new_sc.symbol->GetMangled()) == 0) + { + equivalent_scs = true; + } + } + } + return equivalent_scs; +} +} + void Breakpoint::ModuleReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp) { - ModuleList temp_list; - temp_list.Append (new_module_sp); - ModulesChanged (temp_list, true); + Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); + if (log) + log->Printf ("Breakpoint::ModulesReplaced for %s\n", + old_module_sp->GetSpecificationDescription().c_str()); + // First find all the locations that are in the old module + + BreakpointLocationCollection old_break_locs; + for (BreakpointLocationSP break_loc_sp : m_locations.BreakpointLocations()) + { + SectionSP section_sp = break_loc_sp->GetAddress().GetSection(); + if (section_sp && section_sp->GetModule() == old_module_sp) + { + old_break_locs.Add(break_loc_sp); + } + } + + size_t num_old_locations = old_break_locs.GetSize(); + + if (num_old_locations == 0) + { + // There were no locations in the old module, so we just need to check if there were any in the new module. + ModuleList temp_list; + temp_list.Append (new_module_sp); + ResolveBreakpointInModules(temp_list); + } + else + { + // First search the new module for locations. + // Then compare this with the old list, copy over locations that "look the same" + // Then delete the old locations. + // Finally remember to post the creation event. + // + // Two locations are the same if they have the same comp unit & function (by name) and there are the same number + // of locations in the old function as in the new one. + + ModuleList temp_list; + temp_list.Append (new_module_sp); + BreakpointLocationCollection new_break_locs; + ResolveBreakpointInModules(temp_list, new_break_locs); + BreakpointLocationCollection locations_to_remove; + BreakpointLocationCollection locations_to_announce; + + size_t num_new_locations = new_break_locs.GetSize(); + + if (num_new_locations > 0) + { + // Break out the case of one location -> one location since that's the most common one, and there's no need + // to build up the structures needed for the merge in that case. + if (num_new_locations == 1 && num_old_locations == 1) + { + bool equivalent_locations = false; + SymbolContext old_sc, new_sc; + // The only way the old and new location can be equivalent is if they have the same amount of information: + BreakpointLocationSP old_loc_sp = old_break_locs.GetByIndex(0); + BreakpointLocationSP new_loc_sp = new_break_locs.GetByIndex(0); + + if (old_loc_sp->GetAddress().CalculateSymbolContext(&old_sc) + == new_loc_sp->GetAddress().CalculateSymbolContext(&new_sc)) + { + equivalent_locations = SymbolContextsMightBeEquivalent(old_sc, new_sc); + } + + if (equivalent_locations) + { + m_locations.SwapLocation (old_loc_sp, new_loc_sp); + } + else + { + locations_to_remove.Add(old_loc_sp); + locations_to_announce.Add(new_loc_sp); + } + } + else + { + //We don't want to have to keep computing the SymbolContexts for these addresses over and over, + // so lets get them up front: + + typedef std::map<lldb::break_id_t, SymbolContext> IDToSCMap; + IDToSCMap old_sc_map; + for (size_t idx = 0; idx < num_old_locations; idx++) + { + SymbolContext sc; + BreakpointLocationSP bp_loc_sp = old_break_locs.GetByIndex(idx); + lldb::break_id_t loc_id = bp_loc_sp->GetID(); + bp_loc_sp->GetAddress().CalculateSymbolContext(&old_sc_map[loc_id]); + } + + std::map<lldb::break_id_t, SymbolContext> new_sc_map; + for (size_t idx = 0; idx < num_new_locations; idx++) + { + SymbolContext sc; + BreakpointLocationSP bp_loc_sp = new_break_locs.GetByIndex(idx); + lldb::break_id_t loc_id = bp_loc_sp->GetID(); + bp_loc_sp->GetAddress().CalculateSymbolContext(&new_sc_map[loc_id]); + } + // Take an element from the old Symbol Contexts + while (old_sc_map.size() > 0) + { + lldb::break_id_t old_id = old_sc_map.begin()->first; + SymbolContext &old_sc = old_sc_map.begin()->second; + + // Count the number of entries equivalent to this SC for the old list: + std::vector<lldb::break_id_t> old_id_vec; + old_id_vec.push_back(old_id); + + IDToSCMap::iterator tmp_iter; + for (tmp_iter = ++old_sc_map.begin(); tmp_iter != old_sc_map.end(); tmp_iter++) + { + if (SymbolContextsMightBeEquivalent (old_sc, tmp_iter->second)) + old_id_vec.push_back (tmp_iter->first); + } + + // Now find all the equivalent locations in the new list. + std::vector<lldb::break_id_t> new_id_vec; + for (tmp_iter = new_sc_map.begin(); tmp_iter != new_sc_map.end(); tmp_iter++) + { + if (SymbolContextsMightBeEquivalent (old_sc, tmp_iter->second)) + new_id_vec.push_back(tmp_iter->first); + } + + // Alright, if we have the same number of potentially equivalent locations in the old + // and new modules, we'll just map them one to one in ascending ID order (assuming the + // resolver's order would match the equivalent ones. + // Otherwise, we'll dump all the old ones, and just take the new ones, erasing the elements + // from both maps as we go. + + if (old_id_vec.size() == new_id_vec.size()) + { + sort(old_id_vec.begin(), old_id_vec.end()); + sort(new_id_vec.begin(), new_id_vec.end()); + size_t num_elements = old_id_vec.size(); + for (size_t idx = 0; idx < num_elements; idx++) + { + BreakpointLocationSP old_loc_sp = old_break_locs.FindByIDPair(GetID(), old_id_vec[idx]); + BreakpointLocationSP new_loc_sp = new_break_locs.FindByIDPair(GetID(), new_id_vec[idx]); + m_locations.SwapLocation(old_loc_sp, new_loc_sp); + old_sc_map.erase(old_id_vec[idx]); + new_sc_map.erase(new_id_vec[idx]); + } + } + else + { + for (lldb::break_id_t old_id : old_id_vec) + { + locations_to_remove.Add(old_break_locs.FindByIDPair(GetID(), old_id)); + old_sc_map.erase(old_id); + } + for (lldb::break_id_t new_id : new_id_vec) + { + locations_to_announce.Add(new_break_locs.FindByIDPair(GetID(), new_id)); + new_sc_map.erase(new_id); + } + } + } + } + } + + // Now remove the remaining old locations, and cons up a removed locations event. + // Note, we don't put the new locations that were swapped with an old location on the locations_to_remove + // list, so we don't need to worry about telling the world about removing a location we didn't tell them + // about adding. + + BreakpointEventData *locations_event; + if (!IsInternal()) + locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved, + shared_from_this()); + else + locations_event = NULL; - // TO DO: For now I'm just adding locations for the new module and removing the - // breakpoint locations that were in the old module. - // We should really go find the ones that are in the new module & if we can determine that they are "equivalent" - // carry over the options from the old location to the new. + for (BreakpointLocationSP loc_sp : locations_to_remove.BreakpointLocations()) + { + m_locations.RemoveLocation(loc_sp); + if (locations_event) + locations_event->GetBreakpointLocationCollection().Add(loc_sp); + } + SendBreakpointChangedEvent (locations_event); + + // And announce the new ones. + + if (!IsInternal()) + { + locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded, + shared_from_this()); + for (BreakpointLocationSP loc_sp : locations_to_announce.BreakpointLocations()) + locations_event->GetBreakpointLocationCollection().Add(loc_sp); - temp_list.Clear(); - temp_list.Append (old_module_sp); - ModulesChanged (temp_list, false, true); + SendBreakpointChangedEvent (locations_event); + } + m_locations.Compact(); + } } void @@ -534,6 +783,23 @@ Breakpoint::GetNumLocations() const return m_locations.GetSize(); } +bool +Breakpoint::AddName (const char *new_name, Error &error) +{ + if (!new_name) + return false; + if (!BreakpointID::StringIsBreakpointName(new_name, error)) + { + error.SetErrorStringWithFormat("input name \"%s\" not a breakpoint name.", new_name); + return false; + } + if (!error.Success()) + return false; + + m_name_list.insert(new_name); + return true; +} + void Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations) { @@ -584,6 +850,20 @@ Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_l if (level == lldb::eDescriptionLevelFull) { + if (!m_name_list.empty()) + { + s->EOL(); + s->Indent(); + s->Printf ("Names:"); + s->EOL(); + s->IndentMore(); + for (std::string name : m_name_list) + { + s->Indent(); + s->Printf("%s\n", name.c_str()); + } + s->IndentLess(); + } s->IndentLess(); s->EOL(); } diff --git a/source/Breakpoint/BreakpointID.cpp b/source/Breakpoint/BreakpointID.cpp index 9963ed68303a..31823886dd9f 100644 --- a/source/Breakpoint/BreakpointID.cpp +++ b/source/Breakpoint/BreakpointID.cpp @@ -18,6 +18,7 @@ #include "lldb/Breakpoint/BreakpointID.h" #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Core/Stream.h" +#include "lldb/Core/Error.h" using namespace lldb; using namespace lldb_private; @@ -121,3 +122,19 @@ BreakpointID::ParseCanonicalReference (const char *input, break_id_t *break_id_p return false; } +bool +BreakpointID::StringIsBreakpointName(const char *name, Error &error) +{ + error.Clear(); + + if (name && (name[0] >= 'A' && name[0] <= 'z')) + { + if (strcspn(name, ".- ") != strlen(name)) + { + error.SetErrorStringWithFormat("invalid breakpoint name: \"%s\"", name); + } + return true; + } + else + return false; +} diff --git a/source/Breakpoint/BreakpointIDList.cpp b/source/Breakpoint/BreakpointIDList.cpp index 24101b1442fb..b8b506750b34 100644 --- a/source/Breakpoint/BreakpointIDList.cpp +++ b/source/Breakpoint/BreakpointIDList.cpp @@ -159,27 +159,52 @@ BreakpointIDList::InsertStringArray (const char **string_array, size_t array_siz // NEW_ARGS should be a copy of OLD_ARGS, with and ID range specifiers replaced by the members of the range. void -BreakpointIDList::FindAndReplaceIDRanges (Args &old_args, Target *target, CommandReturnObject &result, +BreakpointIDList::FindAndReplaceIDRanges (Args &old_args, + Target *target, + bool allow_locations, + CommandReturnObject &result, Args &new_args) { std::string range_start; const char *range_end; const char *current_arg; const size_t num_old_args = old_args.GetArgumentCount(); + std::set<std::string> names_found; for (size_t i = 0; i < num_old_args; ++i) { bool is_range = false; + current_arg = old_args.GetArgumentAtIndex (i); + if (!allow_locations && strchr(current_arg, '.') != nullptr) + { + result.AppendErrorWithFormat ("Breakpoint locations not allowed, saw location: %s.", current_arg); + new_args.Clear(); + return; + } size_t range_start_len = 0; size_t range_end_pos = 0; + Error error; + if (BreakpointIDList::StringContainsIDRangeExpression (current_arg, &range_start_len, &range_end_pos)) { is_range = true; range_start.assign (current_arg, range_start_len); range_end = current_arg + range_end_pos; } + else if (BreakpointID::StringIsBreakpointName(current_arg, error)) + { + if (!error.Success()) + { + new_args.Clear(); + result.AppendError (error.AsCString()); + result.SetStatus (eReturnStatusFailed); + return; + } + else + names_found.insert(current_arg); + } else if ((i + 2 < num_old_args) && BreakpointID::IsRangeIdentifier (old_args.GetArgumentAtIndex (i+1)) && BreakpointID::IsValidIDExpression (current_arg) @@ -342,6 +367,23 @@ BreakpointIDList::FindAndReplaceIDRanges (Args &old_args, Target *target, Comman } } + // Okay, now see if we found any names, and if we did, add them: + if (target && names_found.size()) + { + for (BreakpointSP bkpt_sp : target->GetBreakpointList().Breakpoints()) + { + for (std::string name : names_found) + { + if (bkpt_sp->MatchesName(name.c_str())) + { + StreamString canonical_id_str; + BreakpointID::GetCanonicalReference (&canonical_id_str, bkpt_sp->GetID(), LLDB_INVALID_BREAK_ID); + new_args.AppendArgument (canonical_id_str.GetData()); + } + } + } + } + result.SetStatus (eReturnStatusSuccessFinishNoResult); return; } diff --git a/source/Breakpoint/BreakpointLocation.cpp b/source/Breakpoint/BreakpointLocation.cpp index e1ac043ae905..11ecfecc5bc7 100644 --- a/source/Breakpoint/BreakpointLocation.cpp +++ b/source/Breakpoint/BreakpointLocation.cpp @@ -449,8 +449,7 @@ BreakpointLocation::ShouldStop (StoppointCallbackContext *context) bool should_stop = true; Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); - IncrementHitCount(); - + // Do this first, if a location is disabled, it shouldn't increment its hit count. if (!IsEnabled()) return false; @@ -474,6 +473,13 @@ BreakpointLocation::ShouldStop (StoppointCallbackContext *context) return should_stop; } +void +BreakpointLocation::BumpHitCount() +{ + if (IsEnabled()) + IncrementHitCount(); +} + bool BreakpointLocation::IsResolved () const { @@ -569,7 +575,7 @@ BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level) s->PutCString ("re-exported target = "); else s->PutCString("where = "); - sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false); + sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false, true); } else { @@ -717,4 +723,13 @@ BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventTyp m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); } } - + +void +BreakpointLocation::SwapLocation (BreakpointLocationSP swap_from) +{ + m_address = swap_from->m_address; + m_should_resolve_indirect_functions = swap_from->m_should_resolve_indirect_functions; + m_is_reexported = swap_from->m_is_reexported; + m_is_indirect = swap_from->m_is_indirect; + m_user_expression_sp.reset(); +} diff --git a/source/Breakpoint/BreakpointLocationCollection.cpp b/source/Breakpoint/BreakpointLocationCollection.cpp index ee3f56f928d5..5756ccedfaa4 100644 --- a/source/Breakpoint/BreakpointLocationCollection.cpp +++ b/source/Breakpoint/BreakpointLocationCollection.cpp @@ -196,3 +196,4 @@ BreakpointLocationCollection::GetDescription (Stream *s, lldb::DescriptionLevel (*pos)->GetDescription(s, level); } } + diff --git a/source/Breakpoint/BreakpointLocationList.cpp b/source/Breakpoint/BreakpointLocationList.cpp index ae7f863ad090..06b270a08ce9 100644 --- a/source/Breakpoint/BreakpointLocationList.cpp +++ b/source/Breakpoint/BreakpointLocationList.cpp @@ -272,6 +272,20 @@ BreakpointLocationList::AddLocation (const Address &addr, bool resolve_indirect_ return bp_loc_sp; } +void +BreakpointLocationList::SwapLocation (BreakpointLocationSP to_location_sp, BreakpointLocationSP from_location_sp) +{ + if (!from_location_sp || !to_location_sp) + return; + + m_address_to_location.erase(to_location_sp->GetAddress()); + to_location_sp->SwapLocation(from_location_sp); + RemoveLocation(from_location_sp); + m_address_to_location[to_location_sp->GetAddress()] = to_location_sp; + to_location_sp->ResolveBreakpointSite(); +} + + bool BreakpointLocationList::RemoveLocation (const lldb::BreakpointLocationSP &bp_loc_sp) { @@ -345,3 +359,16 @@ BreakpointLocationList::StopRecordingNewLocations () m_new_location_recorder = NULL; } +void +BreakpointLocationList::Compact() +{ + lldb::break_id_t highest_id = 0; + + for (BreakpointLocationSP loc_sp : m_locations) + { + lldb::break_id_t cur_id = loc_sp->GetID(); + if (cur_id > highest_id) + highest_id = cur_id; + } + m_next_id = highest_id; +} diff --git a/source/Breakpoint/BreakpointOptions.cpp b/source/Breakpoint/BreakpointOptions.cpp index ea8556d0930b..db76ffb8685c 100644 --- a/source/Breakpoint/BreakpointOptions.cpp +++ b/source/Breakpoint/BreakpointOptions.cpp @@ -237,8 +237,7 @@ BreakpointOptions::GetDescription (Stream *s, lldb::DescriptionLevel level) cons if (m_thread_spec_ap.get()) m_thread_spec_ap->GetDescription (s, level); - else if (level == eDescriptionLevelBrief) - s->PutCString ("thread spec: no "); + if (level == lldb::eDescriptionLevelFull) { s->IndentLess(); diff --git a/source/Breakpoint/BreakpointResolverAddress.cpp b/source/Breakpoint/BreakpointResolverAddress.cpp index 1bcef93aedad..d6647130c54c 100644 --- a/source/Breakpoint/BreakpointResolverAddress.cpp +++ b/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/source/Breakpoint/BreakpointResolverFileLine.cpp b/source/Breakpoint/BreakpointResolverFileLine.cpp index dcee2fd54125..950054c3d720 100644 --- a/source/Breakpoint/BreakpointResolverFileLine.cpp +++ b/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/source/Breakpoint/BreakpointResolverFileRegex.cpp b/source/Breakpoint/BreakpointResolverFileRegex.cpp index 01aecee7b9c2..c71d9bf5ba8c 100644 --- a/source/Breakpoint/BreakpointResolverFileRegex.cpp +++ b/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/source/Breakpoint/BreakpointResolverName.cpp b/source/Breakpoint/BreakpointResolverName.cpp index 3ac3ed06fc70..581f7b016173 100644 --- a/source/Breakpoint/BreakpointResolverName.cpp +++ b/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/source/Breakpoint/BreakpointSite.cpp b/source/Breakpoint/BreakpointSite.cpp index 3cf6d37af379..469514b03f8a 100644 --- a/source/Breakpoint/BreakpointSite.cpp +++ b/source/Breakpoint/BreakpointSite.cpp @@ -199,6 +199,15 @@ BreakpointSite::ValidForThisThread (Thread *thread) return m_owners.ValidForThisThread(thread); } +void +BreakpointSite::BumpHitCounts() +{ + for (BreakpointLocationSP loc_sp : m_owners.BreakpointLocations()) + { + loc_sp->BumpHitCount(); + } +} + bool BreakpointSite::IntersectsRange(lldb::addr_t addr, size_t size, lldb::addr_t *intersect_addr, size_t *intersect_size, size_t *opcode_offset) const { |