summaryrefslogtreecommitdiff
path: root/source/Breakpoint
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2015-02-06 21:38:51 +0000
committerEd Maste <emaste@FreeBSD.org>2015-02-06 21:38:51 +0000
commit205afe679855a4ce8149cdaa94d3f0868ce796dc (patch)
tree09bc83f73246ee3c7a779605cd0122093d2a8a19 /source/Breakpoint
parent0cac4ca3916ac24ab6139d03cbfd18db9e715bfe (diff)
Diffstat (limited to 'source/Breakpoint')
-rw-r--r--source/Breakpoint/Breakpoint.cpp398
-rw-r--r--source/Breakpoint/BreakpointID.cpp17
-rw-r--r--source/Breakpoint/BreakpointIDList.cpp44
-rw-r--r--source/Breakpoint/BreakpointLocation.cpp23
-rw-r--r--source/Breakpoint/BreakpointLocationCollection.cpp1
-rw-r--r--source/Breakpoint/BreakpointLocationList.cpp27
-rw-r--r--source/Breakpoint/BreakpointOptions.cpp3
-rw-r--r--source/Breakpoint/BreakpointResolverAddress.cpp8
-rw-r--r--source/Breakpoint/BreakpointResolverFileLine.cpp11
-rw-r--r--source/Breakpoint/BreakpointResolverFileRegex.cpp7
-rw-r--r--source/Breakpoint/BreakpointResolverName.cpp18
-rw-r--r--source/Breakpoint/BreakpointSite.cpp9
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
{