[Lldb-commits] [lldb] Add a scripted way to re-present a stop location (PR #158128)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Sep 11 14:27:42 PDT 2025
https://github.com/jimingham updated https://github.com/llvm/llvm-project/pull/158128
>From b5a0c082685a2d76d3eafcfa2b470bed8218aec6 Mon Sep 17 00:00:00 2001
From: Jim Ingham <jingham at apple.com>
Date: Thu, 14 Aug 2025 17:21:04 -0700
Subject: [PATCH 1/2] Add a way for scripted breakpoint resolvers to present
"Facade" locations instead of the actual underlying breakpoint location for
the breakpoint. Also add a "was_hit" method to the scripted resolver that
allows the breakpoint to say which of these "Facade" locations was hit, and
"get_location_description" to provide a description for the facade locations.
rdar://152112327
---
lldb/bindings/python/python-swigsafecast.swig | 4 +
lldb/bindings/python/python-wrapper.swig | 24 +++
lldb/docs/use/python-reference.rst | 61 ++++++
lldb/include/lldb/API/SBBreakpoint.h | 9 +-
lldb/include/lldb/API/SBBreakpointLocation.h | 1 +
lldb/include/lldb/API/SBFrame.h | 3 +-
lldb/include/lldb/Breakpoint/Breakpoint.h | 58 +++++-
.../lldb/Breakpoint/BreakpointLocation.h | 68 ++++++-
.../Breakpoint/BreakpointLocationCollection.h | 2 +-
.../lldb/Breakpoint/BreakpointLocationList.h | 3 +-
.../Breakpoint/BreakpointResolverScripted.h | 6 +
lldb/include/lldb/Breakpoint/BreakpointSite.h | 3 +-
.../lldb/Breakpoint/StopPointSiteList.h | 24 ---
lldb/include/lldb/Breakpoint/StoppointSite.h | 5 +-
.../Interfaces/ScriptedBreakpointInterface.h | 10 +
.../lldb/Interpreter/ScriptInterpreter.h | 6 +
lldb/source/API/SBBreakpoint.cpp | 10 +
lldb/source/Breakpoint/Breakpoint.cpp | 88 +++++++--
lldb/source/Breakpoint/BreakpointLocation.cpp | 177 ++++++++++++++----
.../BreakpointLocationCollection.cpp | 16 +-
.../Breakpoint/BreakpointLocationList.cpp | 11 +-
.../Breakpoint/BreakpointResolverScripted.cpp | 24 ++-
lldb/source/Breakpoint/BreakpointSite.cpp | 5 +-
lldb/source/Interpreter/ScriptInterpreter.cpp | 13 ++
.../ScriptedBreakpointPythonInterface.cpp | 26 +++
.../ScriptedBreakpointPythonInterface.h | 6 +
.../Interfaces/ScriptedPythonInterface.cpp | 47 +++++
.../Interfaces/ScriptedPythonInterface.h | 27 +++
.../Python/SWIGPythonBridge.h | 3 +
lldb/source/Target/StopInfo.cpp | 72 ++++---
.../breakpoint/scripted_bkpt/resolver.py | 1 -
.../breakpoint/scripted_bkpt/was_hit/Makefile | 4 +
.../scripted_bkpt/was_hit/TestWasHit.py | 85 +++++++++
.../scripted_bkpt/was_hit/bkpt_resolver.py | 45 +++++
.../breakpoint/scripted_bkpt/was_hit/main.c | 17 ++
.../Python/PythonTestSuite.cpp | 10 +
36 files changed, 840 insertions(+), 134 deletions(-)
create mode 100644 lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/Makefile
create mode 100644 lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/TestWasHit.py
create mode 100644 lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/bkpt_resolver.py
create mode 100644 lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/main.c
diff --git a/lldb/bindings/python/python-swigsafecast.swig b/lldb/bindings/python/python-swigsafecast.swig
index 4721dfdc17e6a..3ea24f1a31414 100644
--- a/lldb/bindings/python/python-swigsafecast.swig
+++ b/lldb/bindings/python/python-swigsafecast.swig
@@ -142,5 +142,9 @@ PythonObject SWIGBridge::ToSWIGWrapper(
return ToSWIGHelper(module_spec_sb.release(), SWIGTYPE_p_lldb__SBModuleSpec);
}
+PythonObject SWIGBridge::ToSWIGWrapper(lldb::DescriptionLevel level) {
+ return PythonInteger((int64_t) level);
+}
+
} // namespace python
} // namespace lldb_private
diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig
index 2c30d536a753d..64b7dc8381073 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -422,6 +422,30 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *
return sb_ptr;
}
+void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBFrame(PyObject * data) {
+ lldb::SBFrame *sb_ptr = nullptr;
+
+ int valid_cast =
+ SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBFrame, 0);
+
+ if (valid_cast == -1)
+ return NULL;
+
+ return sb_ptr;
+}
+
+void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBBreakpointLocation(PyObject * data) {
+ lldb::SBBreakpointLocation *sb_ptr = nullptr;
+
+ int valid_cast =
+ SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBBreakpointLocation, 0);
+
+ if (valid_cast == -1)
+ return NULL;
+
+ return sb_ptr;
+}
+
void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject * data) {
lldb::SBAttachInfo *sb_ptr = nullptr;
diff --git a/lldb/docs/use/python-reference.rst b/lldb/docs/use/python-reference.rst
index 4292714c9c208..5f40526a7308e 100644
--- a/lldb/docs/use/python-reference.rst
+++ b/lldb/docs/use/python-reference.rst
@@ -420,6 +420,67 @@ of Modules and the list of CompileUnits that will make up the SearchFilter. If
you pass in empty lists, the breakpoint will use the default "search
everywhere,accept everything" filter.
+Providing Facade Locations:
+
+The breakpoint resolver interface also allows you to present a separate set
+of locations for the breakpoint than the ones that actually implement the
+breakpoint in the target.
+
+An example use case for this is if you are providing a debugging interface for a
+library that implements an interpreter for a language lldb can't debug. But
+while debugging that library at the level of the implementation language (e.g. C/C++, etc)
+you would like to offer the ability to "stop when a line in a source language
+file is executed".
+
+You can do this if you know where new lines of code are dispatched in the
+interpreter. You would set a breakpoint there, and then look at the state
+when that breakpoint is hit to see if it is dispatching the source file and
+line that were requested, and stop appropriately.
+
+Facade breakpoint locations are intended to make a more natural presentation
+of that sort of feature. The idea is that you would make a custom breakpoint
+resolver that sets actual locations in the places of interest in the interpreter.
+
+Then your resolver would add "facade locations" that represent the places in the
+interpreted code that you want the breakpoint to stop at, using SBBreakpoint::AddFacadeLocation.
+When lldb describes the breakpoint, it will only show the Facade locations.
+Since facade breakpoint location's description is customizable, you can make these
+locations more descriptive. And when the "real" location is hit, lldb will call the
+"was_hit" method of your resolver. That will return the facade location you
+consider to have been hit this time around, or if you return None, the breakpoint
+will be considered not to have been hit.
+
+Note, this feature is also useful if you don't intend to present facade
+locations since it essentially provides a scripted breakpoint condition. Every
+time one of the locations in your breakpoint is hit, you can run the code in
+your "was_hit" to determine whether to consider the breakpoint hit or not, and
+return the location you were passed in if you want it to be a hit, and None if not.
+
+The Facade location adds these optional affordances to the Resolver class:
+
++------------------------------+----------------------------------------+------------------------------------------------------------------------------------------------------------------+
+| Name | Arguments | Description |
++------------------------------+----------------------------------------+------------------------------------------------------------------------------------------------------------------+
+| ``was_hit`` | ``frame``:`lldb.SBFrame` | This will get called when one of the "real" locations set by your resolver is hit |
+| | ``bp_loc``:`lldb.SBBreakpointLocation` | |
+| | | |
+| | | ``frame`` is the stack frame that hit this location. |
+| | | |
+| | | |
+| | | ``bp_loc`` is the real location that was hit. |
+| | | |
+| | | Return either the facade location that you want to consider hit on this stop, or None if you don't consider |
+| | | any of your facade locations to have been hit. |
++------------------------------+----------------------------------------+------------------------------------------------------------------------------------------------------------------+
+| ``get_location_description`` | ``bp_loc``:`lldb.SBBreakpointLocation` | Use this to provide a helpful description of each facade location. |
+| | ``desc_level``:`lldb.DescriptionLevel` | |
+| | | ``bp_loc`` is the facade location to describe. |
+| | | |
+| | | |
+| | | ``desc_level`` is the level of description requested. The Brief description is printed when the location is |
+| | | hit. Full is printed for `break list` and Verbose for `break list -v`. |
++------------------------------+----------------------------------------+------------------------------------------------------------------------------------------------------------------+
+
Using the python API' to create custom stepping logic
-----------------------------------------------------
diff --git a/lldb/include/lldb/API/SBBreakpoint.h b/lldb/include/lldb/API/SBBreakpoint.h
index 18ed3e7226d3b..3bf87a1b7cc92 100644
--- a/lldb/include/lldb/API/SBBreakpoint.h
+++ b/lldb/include/lldb/API/SBBreakpoint.h
@@ -153,9 +153,16 @@ class LLDB_API SBBreakpoint {
/// fails, e.g. when there aren't enough hardware resources available.
lldb::SBError SetIsHardware(bool is_hardware);
- // Can only be called from a ScriptedBreakpointResolver...
+ /// Adds a location to the breakpoint at the address passed in.
+ /// Can only be called from a ScriptedBreakpointResolver...
SBError
AddLocation(SBAddress &address);
+ /// Add a "Facade location" to the breakpoint. This returns the Facade
+ /// Location that was added, which you can then use in
+ /// get_location_description and was_hit in your breakpoint resolver.
+ /// Can only be called from a ScriptedBreakpointResolver.
+ SBBreakpointLocation
+ AddFacadeLocation();
SBStructuredData SerializeToStructuredData();
diff --git a/lldb/include/lldb/API/SBBreakpointLocation.h b/lldb/include/lldb/API/SBBreakpointLocation.h
index fa823e2b518ac..deda4970cd0ed 100644
--- a/lldb/include/lldb/API/SBBreakpointLocation.h
+++ b/lldb/include/lldb/API/SBBreakpointLocation.h
@@ -24,6 +24,7 @@ class SWIGBridge;
namespace lldb {
class LLDB_API SBBreakpointLocation {
+ friend class lldb_private::ScriptInterpreter;
public:
SBBreakpointLocation();
diff --git a/lldb/include/lldb/API/SBFrame.h b/lldb/include/lldb/API/SBFrame.h
index e4bbcd5ddcd9c..4abb44b4bb0e5 100644
--- a/lldb/include/lldb/API/SBFrame.h
+++ b/lldb/include/lldb/API/SBFrame.h
@@ -225,7 +225,8 @@ class LLDB_API SBFrame {
friend class SBInstruction;
friend class SBThread;
friend class SBValue;
-
+
+ friend class lldb_private::ScriptInterpreter;
friend class lldb_private::python::SWIGBridge;
friend class lldb_private::lua::SWIGBridge;
diff --git a/lldb/include/lldb/Breakpoint/Breakpoint.h b/lldb/include/lldb/Breakpoint/Breakpoint.h
index 26a5e901a0d7e..2bef6a919d878 100644
--- a/lldb/include/lldb/Breakpoint/Breakpoint.h
+++ b/lldb/include/lldb/Breakpoint/Breakpoint.h
@@ -248,6 +248,23 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
/// Returns a pointer to the new location.
lldb::BreakpointLocationSP AddLocation(const Address &addr,
bool *new_location = nullptr);
+ /// Add a `facade` location to the breakpoint's collection of facade locations.
+ /// This is only meant to be called by the breakpoint's resolver.
+ /// Facade locations are placeholders that a scripted breakpoint can use to
+ /// represent the stop locations provided by the breakpoint. The scripted
+ /// breakpoint should record the id of the facade location, and provide
+ /// the description of the location in the GetDescription method
+ /// To emulate hitting a facade location, the breakpoint's WasHit should
+ /// return the ID of the facade that was "hit".
+ ///
+ /// \param[out] new_location
+ /// Set to \b true if a new location was created, to \b false if there
+ /// already was a location at this Address.
+ /// \return
+ /// Returns a pointer to the new location.
+ lldb::BreakpointLocationSP AddFacadeLocation();
+
+ lldb::BreakpointLocationSP GetFacadeLocationByID(lldb::break_id_t);
/// Find a breakpoint location by Address.
///
@@ -268,27 +285,36 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
/// there is no breakpoint location at that address.
lldb::break_id_t FindLocationIDByAddress(const Address &addr);
- /// Find a breakpoint location for a given breakpoint location ID.
+ /// Find a breakpoint location for a given breakpoint location ID. If there
+ /// are Facade Locations in the breakpoint, the facade locations will be
+ /// searched instead of the "real" ones.
///
/// \param[in] bp_loc_id
/// The ID specifying the location.
+ ///
+ /// \param[in] use_facade
+ /// If \b true, then prefer facade locations over "real" ones if they exist.
+ ///
/// \return
/// Returns a shared pointer to the location with ID \a bp_loc_id. The
/// pointer
/// in the shared pointer will be nullptr if there is no location with that
/// ID.
- lldb::BreakpointLocationSP FindLocationByID(lldb::break_id_t bp_loc_id);
+ lldb::BreakpointLocationSP FindLocationByID(lldb::break_id_t bp_loc_id, bool use_facade = true);
/// Get breakpoint locations by index.
///
/// \param[in] index
/// The location index.
///
+ /// \param[in] use_facade
+ /// If \b true, then prefer facade locations over "real" ones if they exist.
+ ///
/// \return
/// Returns a shared pointer to the location with index \a
/// index. The shared pointer might contain nullptr if \a index is
/// greater than then number of actual locations.
- lldb::BreakpointLocationSP GetLocationAtIndex(size_t index);
+ lldb::BreakpointLocationSP GetLocationAtIndex(size_t index, bool use_facade = true);
/// Removes all invalid breakpoint locations.
///
@@ -409,9 +435,12 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
/// Return the number of breakpoint locations that have resolved to actual
/// breakpoint sites.
///
+ /// \param[in] use_facade
+ /// If \b true, then prefer facade locations over "real" ones if they exist.
+ ///
/// \return
/// The number locations resolved breakpoint sites.
- size_t GetNumResolvedLocations() const;
+ size_t GetNumResolvedLocations(bool use_facade = true) const;
/// Return whether this breakpoint has any resolved locations.
///
@@ -421,9 +450,12 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
/// Return the number of breakpoint locations.
///
+ /// \param[in] use_facade
+ /// If \b true, then prefer facade locations over "real" ones if they exist.
+ ///
/// \return
/// The number breakpoint locations.
- size_t GetNumLocations() const;
+ size_t GetNumLocations(bool use_facade = true) const;
/// Put a description of this breakpoint into the stream \a s.
///
@@ -529,6 +561,20 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
m_name_list.erase(name_to_remove);
}
+ enum TypeDisplay {
+ eDisplayFacade = 1,
+ eDisplayReal = 1 << 1,
+ eDisplayHeader = 1 << 2
+ };
+
+ void GetDescriptionForType(Stream *s, lldb::DescriptionLevel level,
+ uint8_t display_type, bool show_locations);
+
+ bool HasFacadeLocations() {
+ return m_facade_locations.GetSize() != 0;
+ }
+
+
public:
bool MatchesName(const char *name) {
return m_name_list.find(name) != m_name_list.end();
@@ -657,6 +703,8 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
BreakpointOptions m_options; // Settable breakpoint options
BreakpointLocationList
m_locations; // The list of locations currently found for this breakpoint.
+ BreakpointLocationCollection m_facade_locations;
+
std::string m_kind_description;
bool m_resolve_indirect_symbols;
diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocation.h b/lldb/include/lldb/Breakpoint/BreakpointLocation.h
index ab2e5e170559d..c4fa9bec51aae 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointLocation.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointLocation.h
@@ -38,6 +38,12 @@ namespace lldb_private {
class BreakpointLocation
: public std::enable_shared_from_this<BreakpointLocation> {
+ friend class BreakpointSite;
+ friend class BreakpointLocationList;
+ friend class Breakpoint;
+ friend class Process;
+ friend class StopInfoBreakpoint;
+
public:
~BreakpointLocation();
@@ -55,16 +61,39 @@ class BreakpointLocation
Target &GetTarget();
+ /// This is a programmatic version of a breakpoint "condition". When a
+ /// breakpoint is hit, WasHit will get called before the synchronous ShouldStop
+ /// callback is run, and if it returns an empty BreakpointLocationSP, lldb will
+ /// act as if that breakpoint wasn't hit.
+ ///
+ /// \param[in] context
+ /// The context at the stop point
+ ///
+ /// \return
+ /// This will return the breakpoint location that was hit on this stop.
+ /// If there was no facade location this will be the original location.
+ /// If the shared pointer is empty, then we'll treat it as if the
+ /// breakpoint was not hit.
+ lldb::BreakpointLocationSP WasHit(StoppointCallbackContext *context);
+
/// Determines whether we should stop due to a hit at this breakpoint
/// location.
///
/// Side Effects: This may evaluate the breakpoint condition, and run the
/// callback. So this command may do a considerable amount of work.
///
+ /// \param[in] context
+ /// The context at the stop point
+ ///
+ /// \param[out] facade_loc_sp
+ /// If this stop should be attributed not to the location that was hit, but
+ /// to a facade location, it will be returned in this facade_loc_sp.
+ ///
/// \return
/// \b true if this breakpoint location thinks we should stop,
/// \b false otherwise.
- bool ShouldStop(StoppointCallbackContext *context);
+ bool ShouldStop(StoppointCallbackContext *context,
+ lldb::BreakpointLocationSP &facade_loc_sp);
// The next section deals with various breakpoint options.
@@ -292,11 +321,6 @@ class BreakpointLocation
}
protected:
- friend class BreakpointSite;
- friend class BreakpointLocationList;
- friend class Process;
- friend class StopInfoBreakpoint;
-
/// Set the breakpoint site for this location to \a bp_site_sp.
///
/// \param[in] bp_site_sp
@@ -346,9 +370,11 @@ class BreakpointLocation
// Constructors and Destructors
//
// Only the Breakpoint can make breakpoint locations, and it owns them.
-
/// Constructor.
///
+ /// \param[in] loc_id
+ /// The location id of the new location.
+ ///
/// \param[in] owner
/// A back pointer to the breakpoint that owns this location.
///
@@ -359,10 +385,25 @@ class BreakpointLocation
/// The thread for which this breakpoint location is valid, or
/// LLDB_INVALID_THREAD_ID if it is valid for all threads.
///
- BreakpointLocation(lldb::break_id_t bid, Breakpoint &owner,
+ BreakpointLocation(lldb::break_id_t loc_id, Breakpoint &owner,
const Address &addr, lldb::tid_t tid,
bool check_for_resolver = true);
+ /// This is the constructor for locations with no address. Currently this is
+ /// just used for Facade locations.
+ ///
+ /// \param[in] loc_id
+ /// The location id of the new location.
+ ///
+ /// \param[in] owner
+ /// A back pointer to the breakpoint that owns this location.
+ ///
+ ///
+public:
+ BreakpointLocation(lldb::break_id_t loc_id, Breakpoint &owner);
+ bool IsValid() const { return m_is_valid; }
+ bool IsFacade() const { return m_is_facade; }
+private:
// Data members:
bool m_should_resolve_indirect_functions;
bool m_is_reexported;
@@ -390,6 +431,17 @@ class BreakpointLocation
/// location was given somewhere in the virtual inlined call stack since the
/// Address always resolves to the lowest entry in the stack.
std::optional<LineEntry> m_preferred_line_entry;
+ bool m_is_valid = true; /// Because Facade locations don't have sites
+ /// we can't use the presence of the site to mean
+ /// this breakpoint is valid, but must manage
+ /// the state directly.
+ bool m_is_facade = false; /// Facade locations aren't directly triggered
+ /// and don't have a breakpoint site. They are
+ /// a useful fiction when you want to represent
+ /// the stop location as something lldb can't
+ /// naturally stop at.
+
+ void SetInvalid() { m_is_valid = false; }
void SetShouldResolveIndirectFunctions(bool do_resolve) {
m_should_resolve_indirect_functions = do_resolve;
diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h b/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h
index 3aef1d658c0e5..8ef13d304d044 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h
@@ -111,7 +111,7 @@ class BreakpointLocationCollection {
///
/// \return
/// \b true if we should stop, \b false otherwise.
- bool ShouldStop(StoppointCallbackContext *context);
+ bool ShouldStop(StoppointCallbackContext *context, BreakpointLocationCollection &stopped_bp_locs);
/// Print a description of the breakpoint locations in this list
/// to the stream \a s.
diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocationList.h b/lldb/include/lldb/Breakpoint/BreakpointLocationList.h
index 17dc0bfe03148..8c8309b731b6b 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointLocationList.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointLocationList.h
@@ -140,7 +140,8 @@ class BreakpointLocationList {
///
/// \return
/// \b true if we should stop, \b false otherwise.
- bool ShouldStop(StoppointCallbackContext *context, lldb::break_id_t breakID);
+ bool ShouldStop(StoppointCallbackContext *context, lldb::break_id_t breakID,
+ lldb::BreakpointLocationSP &bp_loc_sp);
/// Returns the number of elements in this breakpoint location list.
///
diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h b/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h
index 0322fd9f46ede..7e747ab0bdc1f 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h
@@ -45,6 +45,12 @@ class BreakpointResolverScripted : public BreakpointResolver {
void GetDescription(Stream *s) override;
+ lldb::BreakpointLocationSP WasHit(lldb::StackFrameSP frame_sp,
+ lldb::BreakpointLocationSP bp_loc_sp);
+
+ std::optional<std::string> GetLocationDescription(lldb::BreakpointLocationSP bp_loc_sp,
+ lldb::DescriptionLevel level);
+
void Dump(Stream *s) const override;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
diff --git a/lldb/include/lldb/Breakpoint/BreakpointSite.h b/lldb/include/lldb/Breakpoint/BreakpointSite.h
index 7b3f7be23639f..75b5ed9f4f531 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointSite.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointSite.h
@@ -99,7 +99,8 @@ class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>,
///
/// \return
/// \b true if we should stop, \b false otherwise.
- bool ShouldStop(StoppointCallbackContext *context) override;
+ bool ShouldStop(StoppointCallbackContext *context,
+ BreakpointLocationCollection &stopping_bp_loc) override;
/// Standard Dump method
void Dump(Stream *s) const override;
diff --git a/lldb/include/lldb/Breakpoint/StopPointSiteList.h b/lldb/include/lldb/Breakpoint/StopPointSiteList.h
index 7ed53e952dc8d..101eccda4616b 100644
--- a/lldb/include/lldb/Breakpoint/StopPointSiteList.h
+++ b/lldb/include/lldb/Breakpoint/StopPointSiteList.h
@@ -213,30 +213,6 @@ template <typename StopPointSite> class StopPointSiteList {
typedef void (*StopPointSiteSPMapFunc)(StopPointSite &site, void *baton);
- /// Enquires of the site on in this list with ID \a site_id
- /// whether we should stop for the constituent or not.
- ///
- /// \param[in] context
- /// This contains the information about this stop.
- ///
- /// \param[in] site_id
- /// This site ID that we hit.
- ///
- /// \return
- /// \b true if we should stop, \b false otherwise.
- bool ShouldStop(StoppointCallbackContext *context,
- typename StopPointSite::SiteID site_id) {
- if (StopPointSiteSP site_sp = FindByID(site_id)) {
- // Let the site decide if it should stop here (could not have
- // reached it's target hit count yet, or it could have a callback that
- // decided it shouldn't stop (shared library loads/unloads).
- return site_sp->ShouldStop(context);
- }
- // We should stop here since this site isn't valid anymore or it
- // doesn't exist.
- return true;
- }
-
/// Returns the number of elements in the list.
///
/// \result
diff --git a/lldb/include/lldb/Breakpoint/StoppointSite.h b/lldb/include/lldb/Breakpoint/StoppointSite.h
index bef19f37908c6..a398aa838596c 100644
--- a/lldb/include/lldb/Breakpoint/StoppointSite.h
+++ b/lldb/include/lldb/Breakpoint/StoppointSite.h
@@ -38,7 +38,10 @@ class StoppointSite {
virtual bool IsHardware() const = 0;
- virtual bool ShouldStop(StoppointCallbackContext* context) = 0;
+ virtual bool ShouldStop(StoppointCallbackContext* context) { return false; };
+
+ virtual bool ShouldStop(StoppointCallbackContext* context,
+ BreakpointLocationCollection &stopping_bp_locs) { return false; };
virtual void Dump(Stream* stream) const = 0;
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h
index 28d6ed992b141..c203e7f15d279 100644
--- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h
@@ -26,6 +26,16 @@ class ScriptedBreakpointInterface : public ScriptedInterface {
virtual bool ResolverCallback(SymbolContext sym_ctx) { return true; }
virtual lldb::SearchDepth GetDepth() { return lldb::eSearchDepthModule; }
virtual std::optional<std::string> GetShortHelp() { return nullptr; }
+ /// WasHit returns the breakpoint location SP for the location that was "hit".
+ virtual lldb::BreakpointLocationSP WasHit(lldb::StackFrameSP frame_sp,
+ lldb::BreakpointLocationSP bp_loc_sp) {
+ return LLDB_INVALID_BREAK_ID;
+ }
+ virtual std::optional<std::string>
+ GetLocationDescription(lldb::BreakpointLocationSP bp_loc_sp,
+ lldb::DescriptionLevel level) {
+ return {};
+ }
};
} // namespace lldb_private
diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
index 024bbc90a9a39..554f8128344d9 100644
--- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -11,6 +11,7 @@
#include "lldb/API/SBAttachInfo.h"
#include "lldb/API/SBBreakpoint.h"
+#include "lldb/API/SBBreakpointLocation.h"
#include "lldb/API/SBData.h"
#include "lldb/API/SBError.h"
#include "lldb/API/SBEvent.h"
@@ -572,12 +573,17 @@ class ScriptInterpreter : public PluginInterface {
lldb::StreamSP GetOpaqueTypeFromSBStream(const lldb::SBStream &stream) const;
+ lldb::StackFrameSP GetOpaqueTypeFromSBFrame(const lldb::SBFrame &frame) const;
+
SymbolContext
GetOpaqueTypeFromSBSymbolContext(const lldb::SBSymbolContext &sym_ctx) const;
lldb::BreakpointSP
GetOpaqueTypeFromSBBreakpoint(const lldb::SBBreakpoint &breakpoint) const;
+ lldb::BreakpointLocationSP
+ GetOpaqueTypeFromSBBreakpointLocation(const lldb::SBBreakpointLocation &break_loc) const;
+
lldb::ProcessAttachInfoSP
GetOpaqueTypeFromSBAttachInfo(const lldb::SBAttachInfo &attach_info) const;
diff --git a/lldb/source/API/SBBreakpoint.cpp b/lldb/source/API/SBBreakpoint.cpp
index 07c0a2ea907ba..93748dd46f69c 100644
--- a/lldb/source/API/SBBreakpoint.cpp
+++ b/lldb/source/API/SBBreakpoint.cpp
@@ -567,6 +567,16 @@ SBError SBBreakpoint::AddLocation(SBAddress &address) {
return error;
}
+SBBreakpointLocation
+SBBreakpoint::AddFacadeLocation() {
+ BreakpointSP bkpt_sp = GetSP();
+ if (!bkpt_sp) {
+ return {};
+ }
+ BreakpointLocationSP loc_sp = bkpt_sp->AddFacadeLocation();
+ return SBBreakpointLocation(loc_sp);
+}
+
SBStructuredData SBBreakpoint::SerializeToStructuredData() {
LLDB_INSTRUMENT_VA(this);
diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp
index 1544bf85fb859..d6d2f8aa17c19 100644
--- a/lldb/source/Breakpoint/Breakpoint.cpp
+++ b/lldb/source/Breakpoint/Breakpoint.cpp
@@ -58,7 +58,12 @@ Breakpoint::Breakpoint(Target &new_target, const Breakpoint &source_bp)
m_hit_counter() {}
// Destructor
-Breakpoint::~Breakpoint() = default;
+Breakpoint::~Breakpoint() {
+ for (BreakpointLocationSP location_sp : m_locations.BreakpointLocations())
+ location_sp->SetInvalid();
+ for (BreakpointLocationSP location_sp : m_facade_locations.BreakpointLocations())
+ location_sp->SetInvalid();
+}
BreakpointSP Breakpoint::CopyFromBreakpoint(TargetSP new_target,
const Breakpoint &bp_to_copy_from) {
@@ -302,6 +307,19 @@ BreakpointLocationSP Breakpoint::AddLocation(const Address &addr,
new_location);
}
+BreakpointLocationSP Breakpoint::AddFacadeLocation() {
+ size_t next_id = m_facade_locations.GetSize() + 1;
+ BreakpointLocationSP break_loc_sp
+ = std::make_shared<BreakpointLocation>(next_id, *this);
+ break_loc_sp->m_is_facade = true;
+ m_facade_locations.Add(break_loc_sp);
+ return break_loc_sp;
+}
+
+BreakpointLocationSP Breakpoint::GetFacadeLocationByID(lldb::break_id_t loc_id) {
+ return m_facade_locations.GetByIndex(loc_id - 1);
+}
+
BreakpointLocationSP Breakpoint::FindLocationByAddress(const Address &addr) {
return m_locations.FindByAddress(addr);
}
@@ -310,15 +328,21 @@ break_id_t Breakpoint::FindLocationIDByAddress(const Address &addr) {
return m_locations.FindIDByAddress(addr);
}
-BreakpointLocationSP Breakpoint::FindLocationByID(break_id_t bp_loc_id) {
+BreakpointLocationSP Breakpoint::FindLocationByID(break_id_t bp_loc_id, bool use_facade) {
+ if (use_facade && m_facade_locations.GetSize())
+ return GetFacadeLocationByID(bp_loc_id);
return m_locations.FindByID(bp_loc_id);
}
-BreakpointLocationSP Breakpoint::GetLocationAtIndex(size_t index) {
+BreakpointLocationSP Breakpoint::GetLocationAtIndex(size_t index, bool use_facade) {
+ if (use_facade && m_facade_locations.GetSize() > 0)
+ return m_facade_locations.GetByIndex(index);
return m_locations.GetByIndex(index);
}
void Breakpoint::RemoveInvalidLocations(const ArchSpec &arch) {
+ // FIXME: Should we ask the scripted resolver whether any of its facade
+ // locations are invalid?
m_locations.RemoveInvalidLocations(arch);
}
@@ -864,9 +888,15 @@ void Breakpoint::ModuleReplaced(ModuleSP old_module_sp,
void Breakpoint::Dump(Stream *) {}
-size_t Breakpoint::GetNumResolvedLocations() const {
+size_t Breakpoint::GetNumResolvedLocations(bool use_facade) const {
// Return the number of breakpoints that are actually resolved and set down
// in the inferior process.
+ // All facade locations are considered to be resolved:
+ if (use_facade) {
+ size_t num_facade_locs = m_facade_locations.GetSize();
+ if (num_facade_locs)
+ return num_facade_locs;
+ }
return m_locations.GetNumResolvedLocations();
}
@@ -874,7 +904,14 @@ bool Breakpoint::HasResolvedLocations() const {
return GetNumResolvedLocations() > 0;
}
-size_t Breakpoint::GetNumLocations() const { return m_locations.GetSize(); }
+size_t Breakpoint::GetNumLocations(bool use_facade) const {
+ if (use_facade) {
+ size_t num_facade_locs = m_facade_locations.GetSize();
+ if (num_facade_locs > 0)
+ return num_facade_locs;
+ }
+ return m_locations.GetSize();
+}
void Breakpoint::AddName(llvm::StringRef new_name) {
m_name_list.insert(new_name.str());
@@ -899,8 +936,30 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level,
s->Printf("Kind: %s\n", GetBreakpointKind());
}
- const size_t num_locations = GetNumLocations();
- const size_t num_resolved_locations = GetNumResolvedLocations();
+ bool show_both_types = level == eDescriptionLevelVerbose
+ && HasFacadeLocations() && show_locations;
+ uint8_t display_mask = eDisplayFacade;
+ if (show_both_types)
+ display_mask |= eDisplayHeader;
+
+ GetDescriptionForType(s, level, display_mask, show_locations);
+
+ if (show_both_types) {
+ display_mask = eDisplayReal | eDisplayHeader;
+ GetDescriptionForType(s, level, display_mask, show_locations);
+ }
+ // Reset the colors back to normal if they were previously greyed out.
+ if (dim_breakpoint_description)
+ s->Printf("%s", ansi::FormatAnsiTerminalCodes(
+ GetTarget().GetDebugger().GetDisabledAnsiSuffix())
+ .c_str());
+}
+
+void Breakpoint::GetDescriptionForType(Stream *s, lldb::DescriptionLevel level,
+ uint8_t display_type, bool show_locations) {
+ bool use_facade = (display_type & eDisplayFacade) != 0;
+ const size_t num_locations = GetNumLocations(use_facade);
+ const size_t num_resolved_locations = GetNumResolvedLocations(use_facade);
// They just made the breakpoint, they don't need to be told HOW they made
// it... Also, we'll print the breakpoint number differently depending on
@@ -957,7 +1016,7 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level,
} else if (num_locations == 1 && !show_locations) {
// There is only one location, so we'll just print that location
// information.
- GetLocationAtIndex(0)->GetDescription(s, level);
+ GetLocationAtIndex(0, use_facade)->GetDescription(s, level);
} else {
s->Printf("%" PRIu64 " locations.", static_cast<uint64_t>(num_locations));
}
@@ -979,20 +1038,21 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level,
// The brief description is just the location name (1.2 or whatever). That's
// pointless to show in the breakpoint's description, so suppress it.
if (show_locations && level != lldb::eDescriptionLevelBrief) {
+ if ((display_type & eDisplayHeader) != 0)
+ if ((display_type & eDisplayFacade) != 0)
+ s->Printf("Facade locations:\n");
+ else
+ s->Printf("Implementation Locations\n");
+
s->IndentMore();
for (size_t i = 0; i < num_locations; ++i) {
- BreakpointLocation *loc = GetLocationAtIndex(i).get();
+ BreakpointLocation *loc = GetLocationAtIndex(i, use_facade).get();
loc->GetDescription(s, level);
s->EOL();
}
s->IndentLess();
}
- // Reset the colors back to normal if they were previously greyed out.
- if (dim_breakpoint_description)
- s->Printf("%s", ansi::FormatAnsiTerminalCodes(
- GetTarget().GetDebugger().GetDisabledAnsiSuffix())
- .c_str());
}
void Breakpoint::GetResolverDescription(Stream *s) {
diff --git a/lldb/source/Breakpoint/BreakpointLocation.cpp b/lldb/source/Breakpoint/BreakpointLocation.cpp
index 443d4f50833d3..829ed03392999 100644
--- a/lldb/source/Breakpoint/BreakpointLocation.cpp
+++ b/lldb/source/Breakpoint/BreakpointLocation.cpp
@@ -8,6 +8,8 @@
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointID.h"
+#include "lldb/Breakpoint/BreakpointResolver.h"
+#include "lldb/Breakpoint/BreakpointResolverScripted.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
@@ -45,6 +47,13 @@ BreakpointLocation::BreakpointLocation(break_id_t loc_id, Breakpoint &owner,
SetThreadIDInternal(tid);
}
+BreakpointLocation::BreakpointLocation(break_id_t loc_id, Breakpoint &owner)
+ : m_should_resolve_indirect_functions(false), m_is_reexported(false),
+ m_is_indirect(false), m_address(LLDB_INVALID_ADDRESS), m_owner(owner),
+ m_condition_hash(0), m_loc_id(loc_id), m_hit_counter() {
+ SetThreadIDInternal(LLDB_INVALID_THREAD_ID);
+}
+
BreakpointLocation::~BreakpointLocation() {
llvm::consumeError(ClearBreakpointSite());
}
@@ -372,12 +381,41 @@ bool BreakpointLocation::ValidForThisThread(Thread &thread) {
.GetThreadSpecNoCreate());
}
+BreakpointLocationSP BreakpointLocation::WasHit(StoppointCallbackContext *context)
+{
+ // Only the BreakpointResolverScripted provides WasHit.
+ BreakpointResolverSP resolver_sp = GetBreakpoint().GetResolver();
+ BreakpointResolverScripted *scripted = llvm::dyn_cast<BreakpointResolverScripted>(resolver_sp.get());
+ if (!scripted)
+ return shared_from_this();
+
+ StackFrameSP frame_sp = context->exe_ctx_ref.GetFrameSP();
+ if (!frame_sp)
+ return shared_from_this();
+
+ BreakpointLocationSP return_loc_sp = scripted->WasHit(frame_sp, shared_from_this());
+ // If this is a facade location, then we won't have bumped its hit count
+ // while processing the original location hit. Do so here. We don't need
+ // to bump the breakpoint's hit count, however, since hitting the real
+ // location would have already done that.
+ // Also we have to check the enabled state here, since we would never have
+ // gotten here with a real location...
+ if (return_loc_sp && return_loc_sp->IsFacade()) {
+ if (return_loc_sp->IsEnabled())
+ return_loc_sp->m_hit_counter.Increment();
+ else
+ return {};
+ }
+ return return_loc_sp;
+}
+
// RETURNS - true if we should stop at this breakpoint, false if we
// should continue. Note, we don't check the thread spec for the breakpoint
// here, since if the breakpoint is not for this thread, then the event won't
// even get reported, so the check is redundant.
-bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) {
+bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context,
+ lldb::BreakpointLocationSP &facade_loc_sp) {
bool should_stop = true;
Log *log = GetLog(LLDBLog::Breakpoints);
@@ -386,6 +424,27 @@ bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) {
if (!IsEnabled())
return false;
+ // Next check WasHit:
+ BreakpointLocationSP loc_hit_sp = WasHit(context);
+
+ if (!loc_hit_sp) {
+ // We bump the hit counts in StopInfoBreakpoint::ShouldStopSynchronous,
+ // before we call into each location's ShouldStop. So we need to undo
+ // that here.
+ UndoBumpHitCount();
+ return false;
+ }
+
+ // If the location hit was not us, it was a facade location, in which case
+ // we should use the facade location's callbacks, etc. Those will all be
+ // run in the asynchronous phase, so for now we just have to record the fact
+ // that we should treat this as a facade hit. This is strictly an out
+ // parameter, so clear it if this isn't a facade hit.
+ if (loc_hit_sp.get() != this)
+ facade_loc_sp = loc_hit_sp;
+ else
+ facade_loc_sp.reset();
+
// We only run synchronous callbacks in ShouldStop:
context->is_synchronous = true;
should_stop = InvokeCallback(context);
@@ -395,6 +454,11 @@ bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) {
GetDescription(&s, lldb::eDescriptionLevelVerbose);
LLDB_LOGF(log, "Hit breakpoint location: %s, %s.\n", s.GetData(),
should_stop ? "stopping" : "continuing");
+ if (facade_loc_sp) {
+ s.Clear();
+ facade_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
+ LLDB_LOGF(log, "Attributing to facade location: %s.\n", s.GetData());
+ }
}
return should_stop;
@@ -417,7 +481,10 @@ void BreakpointLocation::UndoBumpHitCount() {
}
bool BreakpointLocation::IsResolved() const {
- return m_bp_site_sp.get() != nullptr;
+
+ bool has_site = m_bp_site_sp.get() != nullptr;
+ // Facade locations are currently always considered resolved.
+ return has_site || IsFacade();
}
lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const {
@@ -425,7 +492,9 @@ lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const {
}
llvm::Error BreakpointLocation::ResolveBreakpointSite() {
- if (m_bp_site_sp)
+ // This might be a facade location, which doesn't have an address.
+ // In that case, don't attempt to make a site.
+ if (m_bp_site_sp || IsFacade())
return llvm::Error::success();
Process *process = m_owner.GetTarget().GetProcessSP().get();
@@ -454,8 +523,13 @@ bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) {
}
llvm::Error BreakpointLocation::ClearBreakpointSite() {
- if (!m_bp_site_sp)
- return llvm::createStringError("no breakpoint site to clear");
+ if (!m_bp_site_sp) {
+ // This might be a Facade Location, which don't have sites or addresses
+ if (IsFacade())
+ return llvm::Error::success();
+ else
+ return llvm::createStringError("no breakpoint site to clear");
+ }
// If the process exists, get it to remove the owner, it will remove the
// physical implementation of the breakpoint as well if there are no more
@@ -473,6 +547,17 @@ llvm::Error BreakpointLocation::ClearBreakpointSite() {
void BreakpointLocation::GetDescription(Stream *s,
lldb::DescriptionLevel level) {
SymbolContext sc;
+
+ // If this is a scripted breakpoint, give it a chance to describe its
+ // locations:
+ std::optional<std::string> scripted_opt;
+ BreakpointResolverSP resolver_sp = GetBreakpoint().GetResolver();
+ BreakpointResolverScripted *scripted =
+ llvm::dyn_cast<BreakpointResolverScripted>(resolver_sp.get());
+ if (scripted)
+ scripted_opt = scripted->GetLocationDescription(shared_from_this(), level);
+
+ bool is_scripted_desc = scripted_opt.has_value();
// If the description level is "initial" then the breakpoint is printing out
// our initial state, and we should let it decide how it wants to print our
@@ -491,7 +576,9 @@ void BreakpointLocation::GetDescription(Stream *s,
if (level == lldb::eDescriptionLevelVerbose)
s->IndentMore();
- if (m_address.IsSectionOffset()) {
+ if (is_scripted_desc) {
+ s->PutCString(scripted_opt->c_str());
+ } else if (m_address.IsSectionOffset()) {
m_address.CalculateSymbolContext(&sc);
if (level == lldb::eDescriptionLevelFull ||
@@ -566,43 +653,51 @@ void BreakpointLocation::GetDescription(Stream *s,
s->Indent();
}
- if (m_address.IsSectionOffset() &&
- (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
- s->Printf(", ");
- s->Printf("address = ");
-
- ExecutionContextScope *exe_scope = nullptr;
- Target *target = &m_owner.GetTarget();
- if (target)
- exe_scope = target->GetProcessSP().get();
- if (exe_scope == nullptr)
- exe_scope = target;
-
- if (level == eDescriptionLevelInitial)
- m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
- Address::DumpStyleFileAddress);
- else
- m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
- Address::DumpStyleModuleWithFileAddress);
-
- if (IsIndirect() && m_bp_site_sp) {
- Address resolved_address;
- resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
- Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
- if (resolved_symbol) {
- if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
- s->Printf(", ");
- else if (level == lldb::eDescriptionLevelVerbose) {
- s->EOL();
- s->Indent();
+ if (!is_scripted_desc) {
+ if (m_address.IsSectionOffset() &&
+ (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
+ s->Printf(", ");
+ s->Printf("address = ");
+
+ ExecutionContextScope *exe_scope = nullptr;
+ Target *target = &m_owner.GetTarget();
+ if (target)
+ exe_scope = target->GetProcessSP().get();
+ if (exe_scope == nullptr)
+ exe_scope = target;
+
+ if (level == eDescriptionLevelInitial)
+ m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
+ Address::DumpStyleFileAddress);
+ else
+ m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
+ Address::DumpStyleModuleWithFileAddress);
+
+ if (IsIndirect() && m_bp_site_sp) {
+ Address resolved_address;
+ resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
+ Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
+ if (resolved_symbol) {
+ if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
+ s->Printf(", ");
+ else if (level == lldb::eDescriptionLevelVerbose) {
+ s->EOL();
+ s->Indent();
+ }
+ s->Printf("indirect target = %s",
+ resolved_symbol->GetName().GetCString());
}
- s->Printf("indirect target = %s",
- resolved_symbol->GetName().GetCString());
}
}
- bool is_resolved = IsResolved();
- bool is_hardware = is_resolved && m_bp_site_sp->IsHardware();
+ // Scripted breakpoint are currently always resolved. Does this seem right?
+ // If they don't add any scripted locations, we shouldn't consider them
+ // resolved.
+ bool is_resolved = is_scripted_desc || IsResolved();
+ // A scripted breakpoint might be resolved but not have a site. Be sure to
+ // check for that.
+ bool is_hardware = !is_scripted_desc && IsResolved() && m_bp_site_sp
+ && m_bp_site_sp->IsHardware();
if (level == lldb::eDescriptionLevelVerbose) {
s->EOL();
@@ -717,9 +812,9 @@ void BreakpointLocation::SwapLocation(BreakpointLocationSP swap_from) {
}
void BreakpointLocation::SetThreadIDInternal(lldb::tid_t thread_id) {
- if (thread_id != LLDB_INVALID_THREAD_ID)
+ if (thread_id != LLDB_INVALID_THREAD_ID) {
GetLocationOptions().SetThreadID(thread_id);
- else {
+ } else {
// If we're resetting this to an invalid thread id, then don't make an
// options pointer just to do that.
if (m_options_up != nullptr)
diff --git a/lldb/source/Breakpoint/BreakpointLocationCollection.cpp b/lldb/source/Breakpoint/BreakpointLocationCollection.cpp
index 81bec0bd7583d..1d052c5fc9bb6 100644
--- a/lldb/source/Breakpoint/BreakpointLocationCollection.cpp
+++ b/lldb/source/Breakpoint/BreakpointLocationCollection.cpp
@@ -115,7 +115,8 @@ BreakpointLocationCollection::GetByIndex(size_t i) const {
}
bool BreakpointLocationCollection::ShouldStop(
- StoppointCallbackContext *context) {
+ StoppointCallbackContext *context,
+ BreakpointLocationCollection &stopped_bp_locs) {
bool shouldStop = false;
size_t i = 0;
size_t prev_size = GetSize();
@@ -123,9 +124,20 @@ bool BreakpointLocationCollection::ShouldStop(
// ShouldStop can remove the breakpoint from the list, or even delete
// it, so we should
BreakpointLocationSP cur_loc_sp = GetByIndex(i);
+ BreakpointLocationSP reported_loc_sp;
BreakpointSP keep_bkpt_alive_sp = cur_loc_sp->GetBreakpoint().shared_from_this();
- if (cur_loc_sp->ShouldStop(context))
+ // We're building up the list or which locations claim responsibility for
+ // this stop. If the location's ShouldStop defers to a facade location by
+ // returning a non-null reported location, we want to use that. Otherwise
+ // use the original location.
+ if (cur_loc_sp->ShouldStop(context, reported_loc_sp)) {
+ if (reported_loc_sp)
+ stopped_bp_locs.Add(reported_loc_sp);
+ else
+ stopped_bp_locs.Add(cur_loc_sp);
+
shouldStop = true;
+ }
if (prev_size == GetSize())
i++;
diff --git a/lldb/source/Breakpoint/BreakpointLocationList.cpp b/lldb/source/Breakpoint/BreakpointLocationList.cpp
index 44d1eb5bf7140..5a791d4364641 100644
--- a/lldb/source/Breakpoint/BreakpointLocationList.cpp
+++ b/lldb/source/Breakpoint/BreakpointLocationList.cpp
@@ -32,22 +32,23 @@ BreakpointLocationList::Create(const Address &addr,
std::lock_guard<std::recursive_mutex> guard(m_mutex);
// The location ID is just the size of the location list + 1
lldb::break_id_t bp_loc_id = ++m_next_id;
- BreakpointLocationSP bp_loc_sp(
- new BreakpointLocation(bp_loc_id, m_owner, addr, LLDB_INVALID_THREAD_ID,
- resolve_indirect_symbols));
+ BreakpointLocationSP bp_loc_sp(new
+ BreakpointLocation(bp_loc_id, m_owner, addr, LLDB_INVALID_THREAD_ID,
+ resolve_indirect_symbols));
m_locations.push_back(bp_loc_sp);
m_address_to_location[addr] = bp_loc_sp;
return bp_loc_sp;
}
bool BreakpointLocationList::ShouldStop(StoppointCallbackContext *context,
- lldb::break_id_t break_id) {
+ lldb::break_id_t break_id,
+ lldb::BreakpointLocationSP &bp_loc_sp) {
BreakpointLocationSP bp = FindByID(break_id);
if (bp) {
// Let the BreakpointLocation decide if it should stop here (could not have
// reached it's target hit count yet, or it could have a callback that
// decided it shouldn't stop (shared library loads/unloads).
- return bp->ShouldStop(context);
+ return bp->ShouldStop(context, bp_loc_sp);
}
// We should stop here since this BreakpointLocation isn't valid anymore or
// it doesn't exist.
diff --git a/lldb/source/Breakpoint/BreakpointResolverScripted.cpp b/lldb/source/Breakpoint/BreakpointResolverScripted.cpp
index 701cabae3ee97..b1e45d761735b 100644
--- a/lldb/source/Breakpoint/BreakpointResolverScripted.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverScripted.cpp
@@ -50,7 +50,9 @@ void BreakpointResolverScripted::CreateImplementationIfNeeded(
if (!script_interp)
return;
- m_interface_sp = script_interp->CreateScriptedBreakpointInterface();
+ if (!m_interface_sp)
+ m_interface_sp = script_interp->CreateScriptedBreakpointInterface();
+
if (!m_interface_sp) {
m_error = Status::FromErrorStringWithFormat(
"BreakpointResolverScripted::%s () - ERROR: %s", __FUNCTION__,
@@ -61,6 +63,7 @@ void BreakpointResolverScripted::CreateImplementationIfNeeded(
auto obj_or_err =
m_interface_sp->CreatePluginObject(m_class_name, breakpoint_sp, m_args);
if (!obj_or_err) {
+ m_interface_sp.reset();
m_error = Status::FromError(obj_or_err.takeError());
return;
}
@@ -146,6 +149,8 @@ void BreakpointResolverScripted::GetDescription(Stream *s) {
StructuredData::GenericSP generic_sp;
std::optional<std::string> short_help;
+ CreateImplementationIfNeeded(GetBreakpoint());
+
if (m_interface_sp) {
short_help = m_interface_sp->GetShortHelp();
}
@@ -155,6 +160,23 @@ void BreakpointResolverScripted::GetDescription(Stream *s) {
s->Printf("python class = %s", m_class_name.c_str());
}
+std::optional<std::string>
+BreakpointResolverScripted::GetLocationDescription(
+ lldb::BreakpointLocationSP bp_loc_sp, lldb::DescriptionLevel level) {
+ CreateImplementationIfNeeded(GetBreakpoint());
+ if (m_interface_sp)
+ return m_interface_sp->GetLocationDescription(bp_loc_sp, level);
+ return {};
+}
+
+lldb::BreakpointLocationSP
+BreakpointResolverScripted::WasHit(lldb::StackFrameSP frame_sp, lldb::BreakpointLocationSP bp_loc_sp) {
+ if (m_interface_sp)
+ return m_interface_sp->WasHit(frame_sp, bp_loc_sp);
+
+ return {};
+}
+
void BreakpointResolverScripted::Dump(Stream *s) const {}
lldb::BreakpointResolverSP
diff --git a/lldb/source/Breakpoint/BreakpointSite.cpp b/lldb/source/Breakpoint/BreakpointSite.cpp
index d430e3de788f0..52100b91de09c 100644
--- a/lldb/source/Breakpoint/BreakpointSite.cpp
+++ b/lldb/source/Breakpoint/BreakpointSite.cpp
@@ -45,7 +45,8 @@ break_id_t BreakpointSite::GetNextID() {
// RETURNS - true if we should stop at this breakpoint, false if we
// should continue.
-bool BreakpointSite::ShouldStop(StoppointCallbackContext *context) {
+bool BreakpointSite::ShouldStop(StoppointCallbackContext *context,
+ BreakpointLocationCollection &stopping_bp_locs) {
m_hit_counter.Increment();
// ShouldStop can do a lot of work, and might even come back and hit
// this breakpoint site again. So don't hold the m_constituents_mutex the
@@ -56,7 +57,7 @@ bool BreakpointSite::ShouldStop(StoppointCallbackContext *context) {
std::lock_guard<std::recursive_mutex> guard(m_constituents_mutex);
constituents_copy = m_constituents;
}
- return constituents_copy.ShouldStop(context);
+ return constituents_copy.ShouldStop(context, stopping_bp_locs);
}
bool BreakpointSite::IsBreakpointAtThisSite(lldb::break_id_t bp_id) {
diff --git a/lldb/source/Interpreter/ScriptInterpreter.cpp b/lldb/source/Interpreter/ScriptInterpreter.cpp
index 6a654a0dafe5b..51475db27269b 100644
--- a/lldb/source/Interpreter/ScriptInterpreter.cpp
+++ b/lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -81,6 +81,11 @@ lldb::BreakpointSP ScriptInterpreter::GetOpaqueTypeFromSBBreakpoint(
return breakpoint.m_opaque_wp.lock();
}
+lldb::BreakpointLocationSP ScriptInterpreter::GetOpaqueTypeFromSBBreakpointLocation(
+ const lldb::SBBreakpointLocation &break_loc) const {
+ return break_loc.m_opaque_wp.lock();
+}
+
lldb::ProcessAttachInfoSP ScriptInterpreter::GetOpaqueTypeFromSBAttachInfo(
const lldb::SBAttachInfo &attach_info) const {
return attach_info.m_opaque_sp;
@@ -100,6 +105,14 @@ ScriptInterpreter::GetStatusFromSBError(const lldb::SBError &error) const {
return Status();
}
+lldb::StackFrameSP
+ScriptInterpreter::GetOpaqueTypeFromSBFrame(const lldb::SBFrame &frame) const {
+ if (frame.m_opaque_sp) {
+ return frame.m_opaque_sp->GetFrameSP();
+ }
+ return nullptr;
+}
+
Event *
ScriptInterpreter::GetOpaqueTypeFromSBEvent(const lldb::SBEvent &event) const {
return event.m_opaque_ptr;
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp
index 660edaa0191f0..0c6d23b108fa1 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp
@@ -81,6 +81,32 @@ std::optional<std::string> ScriptedBreakpointPythonInterface::GetShortHelp() {
return obj->GetAsString()->GetValue().str();
}
+lldb::BreakpointLocationSP
+ScriptedBreakpointPythonInterface::WasHit(lldb::StackFrameSP frame_sp, lldb::BreakpointLocationSP bp_loc_sp) {
+ Status py_error;
+ lldb::BreakpointLocationSP loc_sp
+ = Dispatch<lldb::BreakpointLocationSP>("was_hit", py_error, frame_sp, bp_loc_sp);
+
+ if (py_error.Fail())
+ return bp_loc_sp;
+
+ return loc_sp;
+}
+
+std::optional<std::string>
+ScriptedBreakpointPythonInterface::GetLocationDescription(
+ lldb::BreakpointLocationSP bp_loc_sp,
+ lldb::DescriptionLevel level) {
+ Status error;
+ StructuredData::ObjectSP obj = Dispatch("get_location_description", error, bp_loc_sp, level);
+
+ if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
+ error))
+ return {};
+
+ return obj->GetAsString()->GetValue().str();
+}
+
void ScriptedBreakpointPythonInterface::Initialize() {
const std::vector<llvm::StringRef> ci_usages = {
"breakpoint set -P classname [-k key -v value ...]"};
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h
index 27bdd8718ac0c..b8c1219279876 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h
@@ -36,6 +36,12 @@ class ScriptedBreakpointPythonInterface : public ScriptedBreakpointInterface,
bool ResolverCallback(SymbolContext sym_ctx) override;
lldb::SearchDepth GetDepth() override;
std::optional<std::string> GetShortHelp() override;
+ lldb::BreakpointLocationSP WasHit(lldb::StackFrameSP frame_sp,
+ lldb::BreakpointLocationSP bp_loc_sp) override;
+ virtual std::optional<std::string>
+ GetLocationDescription(lldb::BreakpointLocationSP bp_loc_sp,
+ lldb::DescriptionLevel level) override;
+
static void Initialize();
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
index 8083ccae04026..cda8185ef0a17 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
@@ -80,6 +80,19 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StreamSP>(
return nullptr;
}
+template <>
+lldb::StackFrameSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StackFrameSP>(
+ python::PythonObject &p, Status &error) {
+ if (lldb::SBFrame *sb_frame = reinterpret_cast<lldb::SBFrame *>(
+ python::LLDBSWIGPython_CastPyObjectToSBFrame(p.get())))
+ return m_interpreter.GetOpaqueTypeFromSBFrame(*sb_frame);
+ error = Status::FromErrorString(
+ "Couldn't cast lldb::SBFrame to lldb_private::StackFrame.");
+
+ return nullptr;
+}
+
template <>
SymbolContext
ScriptedPythonInterface::ExtractValueFromPythonObject<SymbolContext>(
@@ -126,6 +139,22 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::BreakpointSP>(
return m_interpreter.GetOpaqueTypeFromSBBreakpoint(*sb_breakpoint);
}
+template <>
+lldb::BreakpointLocationSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::BreakpointLocationSP>(
+ python::PythonObject &p, Status &error) {
+ lldb::SBBreakpointLocation *sb_break_loc = reinterpret_cast<lldb::SBBreakpointLocation *>(
+ python::LLDBSWIGPython_CastPyObjectToSBBreakpointLocation(p.get()));
+
+ if (!sb_break_loc) {
+ error = Status::FromErrorStringWithFormat(
+ "Couldn't cast lldb::SBBreakpointLocation to lldb::BreakpointLocationSP.");
+ return nullptr;
+ }
+
+ return m_interpreter.GetOpaqueTypeFromSBBreakpointLocation(*sb_break_loc);
+}
+
template <>
lldb::ProcessAttachInfoSP ScriptedPythonInterface::ExtractValueFromPythonObject<
lldb::ProcessAttachInfoSP>(python::PythonObject &p, Status &error) {
@@ -194,4 +223,22 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<
return m_interpreter.GetOpaqueTypeFromSBExecutionContext(*sb_exe_ctx);
}
+template <>
+lldb::DescriptionLevel
+ScriptedPythonInterface::ExtractValueFromPythonObject<
+ lldb::DescriptionLevel>(python::PythonObject &p, Status &error) {
+ lldb::DescriptionLevel ret_val = lldb::eDescriptionLevelBrief;
+ llvm::Expected<unsigned long long> unsigned_or_err = p.AsUnsignedLongLong();
+ if (!unsigned_or_err) {
+ error = (Status::FromError(unsigned_or_err.takeError()));
+ return ret_val;
+ }
+ unsigned long long unsigned_val = *unsigned_or_err;
+ if (unsigned_val >= lldb::DescriptionLevel::kNumDescriptionLevels) {
+ error = Status("value too large for lldb::DescriptionLevel.");
+ return ret_val;
+ }
+ return static_cast<lldb::DescriptionLevel>(unsigned_val);
+}
+
#endif
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
index f769d3d29add7..57d22d44e565e 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
@@ -436,6 +436,10 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
return python::SWIGBridge::ToSWIGWrapper(arg);
}
+ python::PythonObject Transform(lldb::BreakpointLocationSP arg) {
+ return python::SWIGBridge::ToSWIGWrapper(arg);
+ }
+
python::PythonObject Transform(lldb::ProcessSP arg) {
return python::SWIGBridge::ToSWIGWrapper(arg);
}
@@ -464,10 +468,18 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
return python::SWIGBridge::ToSWIGWrapper(arg.get());
}
+ python::PythonObject Transform(lldb::StackFrameSP arg) {
+ return python::SWIGBridge::ToSWIGWrapper(arg);
+ }
+
python::PythonObject Transform(lldb::DataExtractorSP arg) {
return python::SWIGBridge::ToSWIGWrapper(arg);
}
+ python::PythonObject Transform(lldb::DescriptionLevel arg) {
+ return python::SWIGBridge::ToSWIGWrapper(arg);
+ }
+
template <typename T, typename U>
void ReverseTransform(T &original_arg, U transformed_arg, Status &error) {
// If U is not a PythonObject, don't touch it!
@@ -573,11 +585,21 @@ lldb::StreamSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StreamSP>(
python::PythonObject &p, Status &error);
+template <>
+lldb::StackFrameSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StackFrameSP>(
+ python::PythonObject &p, Status &error);
+
template <>
lldb::BreakpointSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::BreakpointSP>(
python::PythonObject &p, Status &error);
+template <>
+lldb::BreakpointLocationSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::BreakpointLocationSP>(
+ python::PythonObject &p, Status &error);
+
template <>
lldb::ProcessAttachInfoSP ScriptedPythonInterface::ExtractValueFromPythonObject<
lldb::ProcessAttachInfoSP>(python::PythonObject &p, Status &error);
@@ -601,6 +623,11 @@ lldb::ExecutionContextRefSP
ScriptedPythonInterface::ExtractValueFromPythonObject<
lldb::ExecutionContextRefSP>(python::PythonObject &p, Status &error);
+template <>
+lldb::DescriptionLevel
+ScriptedPythonInterface::ExtractValueFromPythonObject<
+ lldb::DescriptionLevel>(python::PythonObject &p, Status &error);
+
} // namespace lldb_private
#endif // LLDB_ENABLE_PYTHON
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
index 413778639c297..7b39d29ba2b20 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -107,6 +107,7 @@ class SWIGBridge {
static PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp);
static PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp);
static PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_extractor_sp);
+ static PythonObject ToSWIGWrapper(lldb::DescriptionLevel level);
static PythonObject
ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb);
@@ -256,11 +257,13 @@ class SWIGBridge {
void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBBreakpointLocation(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBFrame(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBSymbolContext(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data);
void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);
diff --git a/lldb/source/Target/StopInfo.cpp b/lldb/source/Target/StopInfo.cpp
index f47dae2b2465d..b864159ba7471 100644
--- a/lldb/source/Target/StopInfo.cpp
+++ b/lldb/source/Target/StopInfo.cpp
@@ -157,7 +157,7 @@ class StopInfoBreakpoint : public StopInfo {
ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
StoppointCallbackContext context(event_ptr, exe_ctx, true);
bp_site_sp->BumpHitCounts();
- m_should_stop = bp_site_sp->ShouldStop(&context);
+ m_should_stop = bp_site_sp->ShouldStop(&context, m_async_stopped_locs);
} else {
Log *log = GetLog(LLDBLog::Process);
@@ -180,6 +180,7 @@ class StopInfoBreakpoint : public StopInfo {
}
const char *GetDescription() override {
+ // FIXME: only print m_async_stopped_locs.
if (m_description.empty()) {
ThreadSP thread_sp(m_thread_wp.lock());
if (thread_sp) {
@@ -202,7 +203,7 @@ class StopInfoBreakpoint : public StopInfo {
}
strm.Printf("breakpoint ");
- bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief);
+ m_async_stopped_locs.GetDescription(&strm, eDescriptionLevelBrief);
m_description = std::string(strm.GetString());
} else {
StreamString strm;
@@ -244,6 +245,12 @@ class StopInfoBreakpoint : public StopInfo {
}
uint32_t GetStopReasonDataCount() const override {
+ size_t num_async_locs = m_async_stopped_locs.GetSize();
+ // If we have async locations, they are the ones we should report:
+ if (num_async_locs > 0)
+ return num_async_locs * 2;
+
+ // Otherwise report the number of locations at this breakpoint's site.
lldb::BreakpointSiteSP bp_site_sp = GetBreakpointSiteSP();
if (bp_site_sp)
return bp_site_sp->GetNumberOfConstituents() * 2;
@@ -251,22 +258,25 @@ class StopInfoBreakpoint : public StopInfo {
}
uint64_t GetStopReasonDataAtIndex(uint32_t idx) override {
- lldb::BreakpointSiteSP bp_site_sp = GetBreakpointSiteSP();
- if (bp_site_sp) {
- uint32_t bp_index = idx / 2;
- BreakpointLocationSP bp_loc_sp(
- bp_site_sp->GetConstituentAtIndex(bp_index));
- if (bp_loc_sp) {
- if (idx & 1) {
- // FIXME: This might be a Facade breakpoint, so we need to fetch
- // the one that the thread actually hit, not the native loc ID.
-
- // Odd idx, return the breakpoint location ID
- return bp_loc_sp->GetID();
- } else {
- // Even idx, return the breakpoint ID
- return bp_loc_sp->GetBreakpoint().GetID();
- }
+ uint32_t bp_index = idx / 2;
+ BreakpointLocationSP loc_to_report_sp;
+
+ size_t num_async_locs = m_async_stopped_locs.GetSize();
+ if (num_async_locs > 0) {
+ // GetByIndex returns an empty SP if we ask past its contents:
+ loc_to_report_sp = m_async_stopped_locs.GetByIndex(bp_index);
+ } else {
+ lldb::BreakpointSiteSP bp_site_sp = GetBreakpointSiteSP();
+ if (bp_site_sp)
+ loc_to_report_sp = bp_site_sp->GetConstituentAtIndex(bp_index);
+ }
+ if (loc_to_report_sp) {
+ if (idx & 1) {
+ // Odd idx, return the breakpoint location ID
+ return loc_to_report_sp->GetID();
+ } else {
+ // Even idx, return the breakpoint ID
+ return loc_to_report_sp->GetBreakpoint().GetID();
}
}
return LLDB_INVALID_BREAK_ID;
@@ -336,7 +346,7 @@ class StopInfoBreakpoint : public StopInfo {
// site, then we won't be operating on a bad list.
BreakpointLocationCollection site_locations;
size_t num_constituents =
- bp_site_sp->CopyConstituentsList(site_locations);
+ m_async_stopped_locs.GetSize();
if (num_constituents == 0) {
m_should_stop = true;
@@ -435,17 +445,28 @@ class StopInfoBreakpoint : public StopInfo {
// breakpoints, and the locations don't keep their constituents alive.
// I'm just sticking the BreakpointSP's in a vector since I'm only
// using it to locally increment their retain counts.
-
+
+ // We are holding onto the breakpoint locations that were hit
+ // by this stop info between the "synchonous" ShouldStop and now.
+ // But an intervening action might have deleted one of the breakpoints
+ // we hit before we get here. So at the same time let's build a list
+ // of the still valid locations:
std::vector<lldb::BreakpointSP> location_constituents;
+ BreakpointLocationCollection valid_locs;
for (size_t j = 0; j < num_constituents; j++) {
- BreakpointLocationSP loc(site_locations.GetByIndex(j));
- location_constituents.push_back(
- loc->GetBreakpoint().shared_from_this());
+ BreakpointLocationSP loc_sp(m_async_stopped_locs.GetByIndex(j));
+ if (loc_sp->IsValid()) {
+ location_constituents.push_back(
+ loc_sp->GetBreakpoint().shared_from_this());
+ valid_locs.Add(loc_sp);
+ }
}
- for (size_t j = 0; j < num_constituents; j++) {
- lldb::BreakpointLocationSP bp_loc_sp = site_locations.GetByIndex(j);
+ size_t num_valid_locs = valid_locs.GetSize();
+ for (size_t j = 0; j < num_valid_locs; j++) {
+ lldb::BreakpointLocationSP bp_loc_sp
+ = valid_locs.GetByIndex(j);
StreamString loc_desc;
if (log) {
bp_loc_sp->GetDescription(&loc_desc, eDescriptionLevelBrief);
@@ -679,6 +700,7 @@ class StopInfoBreakpoint : public StopInfo {
lldb::break_id_t m_break_id;
bool m_was_all_internal;
bool m_was_one_shot;
+ BreakpointLocationCollection m_async_stopped_locs;
};
// StopInfoWatchpoint
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/resolver.py b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/resolver.py
index 85c7340127615..95868486b8cba 100644
--- a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/resolver.py
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/resolver.py
@@ -51,7 +51,6 @@ def __callback__(self, sym_ctx):
def get_short_help(self):
return "I am a python breakpoint resolver"
-
class ResolverModuleDepth(Resolver):
def __get_depth__(self):
return lldb.eSearchDepthModule
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/Makefile b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/Makefile
new file mode 100644
index 0000000000000..695335e068c0c
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/Makefile
@@ -0,0 +1,4 @@
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -std=c99
+
+include Makefile.rules
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/TestWasHit.py b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/TestWasHit.py
new file mode 100644
index 0000000000000..de178f5b04fc7
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/TestWasHit.py
@@ -0,0 +1,85 @@
+"""
+Test the WasHit feature of scripted breakpoints
+"""
+
+import os
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+
+
+class TestWasHit(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")
+ def test_was_hit_resolver(self):
+ """Use facade breakpoints to emulate hitting some locations"""
+ self.build()
+ self.do_test()
+
+ def make_target_and_import(self):
+ target = lldbutil.run_to_breakpoint_make_target(self)
+ self.import_resolver_script()
+ return target
+
+ def import_resolver_script(self):
+ interp = self.dbg.GetCommandInterpreter()
+ error = lldb.SBError()
+
+ script_name = os.path.join(self.getSourceDir(), "bkpt_resolver.py")
+
+ command = "command script import " + script_name
+ self.runCmd(command)
+
+ def make_extra_args(self, sym_name, num_locs, loc_to_miss):
+ return f' -k symbol -v {sym_name} -k num_locs -v {num_locs} -k loc_to_miss -v {loc_to_miss} '
+
+ def do_test(self):
+ """This reads in a python file and sets a breakpoint using it."""
+
+ target = self.make_target_and_import()
+ extra_args = self.make_extra_args("stop_symbol", 4, 2)
+
+ bkpt_no = lldbutil.run_break_set_by_script(self, "bkpt_resolver.FacadeExample", extra_args, 4)
+
+ # Make sure the help text shows up in the "break list" output:
+ self.expect(
+ "break list",
+ substrs=["I am a facade resolver - sym: stop_symbol - num_locs: 4"],
+ msg="Help is listed in break list",
+ )
+
+ bkpt = target.FindBreakpointByID(bkpt_no)
+ self.assertTrue(bkpt.IsValid(), "Found the right breakpoint")
+
+ # Now continue. We should hit locations 1, 3 and 4:
+ (target, process, thread, bkpt) = lldbutil.run_to_breakpoint_do_run(self, target, bkpt)
+ # This location should be bkpt_no.1:
+ self.assertEqual(thread.stop_reason_data[0], bkpt_no, "Hit the right breakpoint")
+ self.assertEqual(thread.stop_reason_data[1], 1, "First location hit is 1")
+
+ for loc in [3, 4]:
+ process.Continue()
+ self.assertEqual(thread.stop_reason, lldb.eStopReasonBreakpoint, "Hit breakpoint")
+ self.assertEqual(thread.stop_reason_data[0], bkpt_no, "Hit the right breakpoint")
+ self.assertEqual(thread.stop_reason_data[1], loc, f"Hit the right location: {loc}")
+
+ # At this point we should have hit three of the four locations, and not location 1.2.
+ # Check that that is true, and that the descriptions for the location are the ones
+ # the resolver provided.
+ self.assertEqual(bkpt.hit_count, 3, "Hit three locations")
+ for loc_id in range(1,4):
+ bkpt_loc = bkpt.FindLocationByID(loc_id)
+ self.assertTrue(bkpt_loc.IsValid(), f"{loc_id} was invalid.")
+ if loc_id != 2:
+ self.assertEqual(bkpt_loc.hit_count, 1, f"Loc {loc_id} hit count was wrong")
+ else:
+ self.assertEqual(bkpt_loc.hit_count, 0, "We didn't skip loc 2")
+ stream = lldb.SBStream()
+ self.assertTrue(bkpt_loc.GetDescription(stream, lldb.eDescriptionLevelFull),
+ f"Didn't get description for {loc_id}")
+ self.assertIn(f"Location index: {loc_id}", stream.GetData(),
+ f"Wrong desciption for {loc_id}")
+
+
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/bkpt_resolver.py b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/bkpt_resolver.py
new file mode 100644
index 0000000000000..004ee18513f2f
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/bkpt_resolver.py
@@ -0,0 +1,45 @@
+import lldb
+
+class FacadeExample:
+ def __init__(self, bkpt, extra_args, dict):
+ self.bkpt = bkpt
+ self.extra_args = extra_args
+ self.base_sym = None
+ self.facade_locs = []
+ self.facade_locs_desc = []
+ self.cur_facade_loc = 1
+
+ self.sym_name = extra_args.GetValueForKey("symbol").GetStringValue(100)
+ self.num_locs = extra_args.GetValueForKey("num_locs").GetIntegerValue(5)
+ self.loc_to_miss = extra_args.GetValueForKey("loc_to_miss").GetIntegerValue(10000)
+
+ def __callback__(self, sym_ctx):
+ self.base_sym = sym_ctx.module.FindSymbol(self.sym_name, lldb.eSymbolTypeCode)
+ if self.base_sym.IsValid():
+ self.bkpt.AddLocation(self.base_sym.GetStartAddress())
+ # Locations are 1 based, so to keep things simple, I'm making
+ # the array holding locations 1 based as well:
+ self.facade_locs_desc.append("This is the zero index, you shouldn't see this")
+ self.facade_locs.append(None)
+ for i in range(1, self.num_locs + 1):
+ self.facade_locs_desc.append(f"Location index: {i}")
+ self.facade_locs.append(self.bkpt.AddFacadeLocation())
+
+ def get_short_help(self):
+ return f"I am a facade resolver - sym: {self.sym_name} - num_locs: {self.num_locs} - locs_to_miss: {self.loc_to_miss}"
+
+ def was_hit(self, frame, bp_loc):
+ tmp_loc = self.cur_facade_loc
+
+ self.cur_facade_loc = (self.cur_facade_loc + 1)
+ if self.cur_facade_loc == 5:
+ self.cur_facade_loc = 1
+
+ if tmp_loc == self.loc_to_miss:
+ return None
+
+ return self.facade_locs[tmp_loc]
+
+ def get_location_description(self, bp_loc, desc_level):
+ return self.facade_locs_desc[bp_loc.id]
+
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/main.c b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/main.c
new file mode 100644
index 0000000000000..762553109f7f7
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/main.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int
+stop_symbol() {
+ static int s_cnt = 0;
+ printf("I am in the stop symbol: %d\n", s_cnt++);
+ return s_cnt;
+}
+
+int
+main()
+{
+ for (int i = 0; i < 100; i++) {
+ stop_symbol();
+ }
+ return 0;
+}
diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
index 068860ebc20f1..6f5d9fd97ee28 100644
--- a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -105,6 +105,11 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBBreakpoint(
return nullptr;
}
+void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBBreakpointLocation(
+ PyObject *data) {
+ return nullptr;
+}
+
void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBAttachInfo(
PyObject *data) {
return nullptr;
@@ -130,6 +135,11 @@ lldb_private::python::LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data) {
return nullptr;
}
+void *
+lldb_private::python::LLDBSWIGPython_CastPyObjectToSBFrame(PyObject *data) {
+ return nullptr;
+}
+
void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBSymbolContext(
PyObject *data) {
return nullptr;
>From 5001e68b96beae7596b2100bf275dac4eaa5d990 Mon Sep 17 00:00:00 2001
From: Jim Ingham <jingham at apple.com>
Date: Thu, 11 Sep 2025 14:27:21 -0700
Subject: [PATCH 2/2] Formatting.
---
lldb/include/lldb/API/SBBreakpoint.h | 7 ++-
lldb/include/lldb/API/SBBreakpointLocation.h | 1 +
lldb/include/lldb/API/SBFrame.h | 2 +-
lldb/include/lldb/Breakpoint/Breakpoint.h | 29 ++++++-----
.../lldb/Breakpoint/BreakpointLocation.h | 33 +++++++------
.../Breakpoint/BreakpointLocationCollection.h | 3 +-
.../lldb/Breakpoint/BreakpointLocationList.h | 4 +-
.../Breakpoint/BreakpointResolverScripted.h | 9 ++--
lldb/include/lldb/Breakpoint/BreakpointSite.h | 4 +-
lldb/include/lldb/Breakpoint/StoppointSite.h | 8 +--
.../Interfaces/ScriptedBreakpointInterface.h | 14 +++---
.../lldb/Interpreter/ScriptInterpreter.h | 4 +-
lldb/source/API/SBBreakpoint.cpp | 3 +-
lldb/source/Breakpoint/Breakpoint.cpp | 34 +++++++------
lldb/source/Breakpoint/BreakpointLocation.cpp | 40 ++++++++-------
.../Breakpoint/BreakpointLocationList.cpp | 6 +--
.../Breakpoint/BreakpointResolverScripted.cpp | 8 +--
lldb/source/Breakpoint/BreakpointSite.cpp | 5 +-
lldb/source/Interpreter/ScriptInterpreter.cpp | 3 +-
.../ScriptedBreakpointPythonInterface.cpp | 16 +++---
.../ScriptedBreakpointPythonInterface.h | 12 ++---
.../Interfaces/ScriptedPythonInterface.cpp | 40 ++++++++-------
.../Interfaces/ScriptedPythonInterface.h | 8 +--
lldb/source/Target/StopInfo.cpp | 11 ++---
.../scripted_bkpt/was_hit/TestWasHit.py | 49 +++++++++++++------
.../scripted_bkpt/was_hit/bkpt_resolver.py | 16 +++---
.../breakpoint/scripted_bkpt/was_hit/main.c | 7 +--
27 files changed, 203 insertions(+), 173 deletions(-)
diff --git a/lldb/include/lldb/API/SBBreakpoint.h b/lldb/include/lldb/API/SBBreakpoint.h
index 3bf87a1b7cc92..fe19ba998ea67 100644
--- a/lldb/include/lldb/API/SBBreakpoint.h
+++ b/lldb/include/lldb/API/SBBreakpoint.h
@@ -157,12 +157,11 @@ class LLDB_API SBBreakpoint {
/// Can only be called from a ScriptedBreakpointResolver...
SBError
AddLocation(SBAddress &address);
- /// Add a "Facade location" to the breakpoint. This returns the Facade
- /// Location that was added, which you can then use in
+ /// Add a "Facade location" to the breakpoint. This returns the Facade
+ /// Location that was added, which you can then use in
/// get_location_description and was_hit in your breakpoint resolver.
/// Can only be called from a ScriptedBreakpointResolver.
- SBBreakpointLocation
- AddFacadeLocation();
+ SBBreakpointLocation AddFacadeLocation();
SBStructuredData SerializeToStructuredData();
diff --git a/lldb/include/lldb/API/SBBreakpointLocation.h b/lldb/include/lldb/API/SBBreakpointLocation.h
index deda4970cd0ed..9b0d4839aca82 100644
--- a/lldb/include/lldb/API/SBBreakpointLocation.h
+++ b/lldb/include/lldb/API/SBBreakpointLocation.h
@@ -25,6 +25,7 @@ namespace lldb {
class LLDB_API SBBreakpointLocation {
friend class lldb_private::ScriptInterpreter;
+
public:
SBBreakpointLocation();
diff --git a/lldb/include/lldb/API/SBFrame.h b/lldb/include/lldb/API/SBFrame.h
index 4abb44b4bb0e5..92917e57fc125 100644
--- a/lldb/include/lldb/API/SBFrame.h
+++ b/lldb/include/lldb/API/SBFrame.h
@@ -225,7 +225,7 @@ class LLDB_API SBFrame {
friend class SBInstruction;
friend class SBThread;
friend class SBValue;
-
+
friend class lldb_private::ScriptInterpreter;
friend class lldb_private::python::SWIGBridge;
friend class lldb_private::lua::SWIGBridge;
diff --git a/lldb/include/lldb/Breakpoint/Breakpoint.h b/lldb/include/lldb/Breakpoint/Breakpoint.h
index 2bef6a919d878..bcb5d0ea7622b 100644
--- a/lldb/include/lldb/Breakpoint/Breakpoint.h
+++ b/lldb/include/lldb/Breakpoint/Breakpoint.h
@@ -248,8 +248,8 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
/// Returns a pointer to the new location.
lldb::BreakpointLocationSP AddLocation(const Address &addr,
bool *new_location = nullptr);
- /// Add a `facade` location to the breakpoint's collection of facade locations.
- /// This is only meant to be called by the breakpoint's resolver.
+ /// Add a `facade` location to the breakpoint's collection of facade
+ /// locations. This is only meant to be called by the breakpoint's resolver.
/// Facade locations are placeholders that a scripted breakpoint can use to
/// represent the stop locations provided by the breakpoint. The scripted
/// breakpoint should record the id of the facade location, and provide
@@ -263,7 +263,7 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
/// \return
/// Returns a pointer to the new location.
lldb::BreakpointLocationSP AddFacadeLocation();
-
+
lldb::BreakpointLocationSP GetFacadeLocationByID(lldb::break_id_t);
/// Find a breakpoint location by Address.
@@ -293,14 +293,15 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
/// The ID specifying the location.
///
/// \param[in] use_facade
- /// If \b true, then prefer facade locations over "real" ones if they exist.
+ /// If \b true, then prefer facade locations over "real" ones if they exist.
///
/// \return
/// Returns a shared pointer to the location with ID \a bp_loc_id. The
/// pointer
/// in the shared pointer will be nullptr if there is no location with that
/// ID.
- lldb::BreakpointLocationSP FindLocationByID(lldb::break_id_t bp_loc_id, bool use_facade = true);
+ lldb::BreakpointLocationSP FindLocationByID(lldb::break_id_t bp_loc_id,
+ bool use_facade = true);
/// Get breakpoint locations by index.
///
@@ -308,13 +309,14 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
/// The location index.
///
/// \param[in] use_facade
- /// If \b true, then prefer facade locations over "real" ones if they exist.
+ /// If \b true, then prefer facade locations over "real" ones if they exist.
///
/// \return
/// Returns a shared pointer to the location with index \a
/// index. The shared pointer might contain nullptr if \a index is
/// greater than then number of actual locations.
- lldb::BreakpointLocationSP GetLocationAtIndex(size_t index, bool use_facade = true);
+ lldb::BreakpointLocationSP GetLocationAtIndex(size_t index,
+ bool use_facade = true);
/// Removes all invalid breakpoint locations.
///
@@ -436,7 +438,7 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
/// breakpoint sites.
///
/// \param[in] use_facade
- /// If \b true, then prefer facade locations over "real" ones if they exist.
+ /// If \b true, then prefer facade locations over "real" ones if they exist.
///
/// \return
/// The number locations resolved breakpoint sites.
@@ -451,7 +453,7 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
/// Return the number of breakpoint locations.
///
/// \param[in] use_facade
- /// If \b true, then prefer facade locations over "real" ones if they exist.
+ /// If \b true, then prefer facade locations over "real" ones if they exist.
///
/// \return
/// The number breakpoint locations.
@@ -563,17 +565,14 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
enum TypeDisplay {
eDisplayFacade = 1,
- eDisplayReal = 1 << 1,
+ eDisplayReal = 1 << 1,
eDisplayHeader = 1 << 2
};
void GetDescriptionForType(Stream *s, lldb::DescriptionLevel level,
- uint8_t display_type, bool show_locations);
-
- bool HasFacadeLocations() {
- return m_facade_locations.GetSize() != 0;
- }
+ uint8_t display_type, bool show_locations);
+ bool HasFacadeLocations() { return m_facade_locations.GetSize() != 0; }
public:
bool MatchesName(const char *name) {
diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocation.h b/lldb/include/lldb/Breakpoint/BreakpointLocation.h
index c4fa9bec51aae..6557a23a47911 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointLocation.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointLocation.h
@@ -62,17 +62,17 @@ class BreakpointLocation
Target &GetTarget();
/// This is a programmatic version of a breakpoint "condition". When a
- /// breakpoint is hit, WasHit will get called before the synchronous ShouldStop
- /// callback is run, and if it returns an empty BreakpointLocationSP, lldb will
- /// act as if that breakpoint wasn't hit.
+ /// breakpoint is hit, WasHit will get called before the synchronous
+ /// ShouldStop callback is run, and if it returns an empty
+ /// BreakpointLocationSP, lldb will act as if that breakpoint wasn't hit.
///
/// \param[in] context
/// The context at the stop point
- ///
+ ///
/// \return
/// This will return the breakpoint location that was hit on this stop.
/// If there was no facade location this will be the original location.
- /// If the shared pointer is empty, then we'll treat it as if the
+ /// If the shared pointer is empty, then we'll treat it as if the
/// breakpoint was not hit.
lldb::BreakpointLocationSP WasHit(StoppointCallbackContext *context);
@@ -84,16 +84,16 @@ class BreakpointLocation
///
/// \param[in] context
/// The context at the stop point
- ///
+ ///
/// \param[out] facade_loc_sp
/// If this stop should be attributed not to the location that was hit, but
/// to a facade location, it will be returned in this facade_loc_sp.
- ///
+ ///
/// \return
/// \b true if this breakpoint location thinks we should stop,
/// \b false otherwise.
- bool ShouldStop(StoppointCallbackContext *context,
- lldb::BreakpointLocationSP &facade_loc_sp);
+ bool ShouldStop(StoppointCallbackContext *context,
+ lldb::BreakpointLocationSP &facade_loc_sp);
// The next section deals with various breakpoint options.
@@ -373,7 +373,7 @@ class BreakpointLocation
/// Constructor.
///
/// \param[in] loc_id
- /// The location id of the new location.
+ /// The location id of the new location.
///
/// \param[in] owner
/// A back pointer to the breakpoint that owns this location.
@@ -390,10 +390,10 @@ class BreakpointLocation
bool check_for_resolver = true);
/// This is the constructor for locations with no address. Currently this is
- /// just used for Facade locations.
+ /// just used for Facade locations.
///
/// \param[in] loc_id
- /// The location id of the new location.
+ /// The location id of the new location.
///
/// \param[in] owner
/// A back pointer to the breakpoint that owns this location.
@@ -403,6 +403,7 @@ class BreakpointLocation
BreakpointLocation(lldb::break_id_t loc_id, Breakpoint &owner);
bool IsValid() const { return m_is_valid; }
bool IsFacade() const { return m_is_facade; }
+
private:
// Data members:
bool m_should_resolve_indirect_functions;
@@ -431,10 +432,10 @@ class BreakpointLocation
/// location was given somewhere in the virtual inlined call stack since the
/// Address always resolves to the lowest entry in the stack.
std::optional<LineEntry> m_preferred_line_entry;
- bool m_is_valid = true; /// Because Facade locations don't have sites
- /// we can't use the presence of the site to mean
- /// this breakpoint is valid, but must manage
- /// the state directly.
+ bool m_is_valid = true; /// Because Facade locations don't have sites
+ /// we can't use the presence of the site to mean
+ /// this breakpoint is valid, but must manage
+ /// the state directly.
bool m_is_facade = false; /// Facade locations aren't directly triggered
/// and don't have a breakpoint site. They are
/// a useful fiction when you want to represent
diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h b/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h
index 8ef13d304d044..1df4e074680f5 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h
@@ -111,7 +111,8 @@ class BreakpointLocationCollection {
///
/// \return
/// \b true if we should stop, \b false otherwise.
- bool ShouldStop(StoppointCallbackContext *context, BreakpointLocationCollection &stopped_bp_locs);
+ bool ShouldStop(StoppointCallbackContext *context,
+ BreakpointLocationCollection &stopped_bp_locs);
/// Print a description of the breakpoint locations in this list
/// to the stream \a s.
diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocationList.h b/lldb/include/lldb/Breakpoint/BreakpointLocationList.h
index 8c8309b731b6b..952db559d6cc7 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointLocationList.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointLocationList.h
@@ -140,8 +140,8 @@ class BreakpointLocationList {
///
/// \return
/// \b true if we should stop, \b false otherwise.
- bool ShouldStop(StoppointCallbackContext *context, lldb::break_id_t breakID,
- lldb::BreakpointLocationSP &bp_loc_sp);
+ bool ShouldStop(StoppointCallbackContext *context, lldb::break_id_t breakID,
+ lldb::BreakpointLocationSP &bp_loc_sp);
/// Returns the number of elements in this breakpoint location list.
///
diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h b/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h
index 7e747ab0bdc1f..c3c1c80f49043 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h
@@ -45,11 +45,12 @@ class BreakpointResolverScripted : public BreakpointResolver {
void GetDescription(Stream *s) override;
- lldb::BreakpointLocationSP WasHit(lldb::StackFrameSP frame_sp,
+ lldb::BreakpointLocationSP WasHit(lldb::StackFrameSP frame_sp,
lldb::BreakpointLocationSP bp_loc_sp);
-
- std::optional<std::string> GetLocationDescription(lldb::BreakpointLocationSP bp_loc_sp,
- lldb::DescriptionLevel level);
+
+ std::optional<std::string>
+ GetLocationDescription(lldb::BreakpointLocationSP bp_loc_sp,
+ lldb::DescriptionLevel level);
void Dump(Stream *s) const override;
diff --git a/lldb/include/lldb/Breakpoint/BreakpointSite.h b/lldb/include/lldb/Breakpoint/BreakpointSite.h
index 75b5ed9f4f531..a935b2441c02a 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointSite.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointSite.h
@@ -99,8 +99,8 @@ class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>,
///
/// \return
/// \b true if we should stop, \b false otherwise.
- bool ShouldStop(StoppointCallbackContext *context,
- BreakpointLocationCollection &stopping_bp_loc) override;
+ bool ShouldStop(StoppointCallbackContext *context,
+ BreakpointLocationCollection &stopping_bp_loc) override;
/// Standard Dump method
void Dump(Stream *s) const override;
diff --git a/lldb/include/lldb/Breakpoint/StoppointSite.h b/lldb/include/lldb/Breakpoint/StoppointSite.h
index a398aa838596c..2ceac403940ef 100644
--- a/lldb/include/lldb/Breakpoint/StoppointSite.h
+++ b/lldb/include/lldb/Breakpoint/StoppointSite.h
@@ -38,10 +38,12 @@ class StoppointSite {
virtual bool IsHardware() const = 0;
- virtual bool ShouldStop(StoppointCallbackContext* context) { return false; };
+ virtual bool ShouldStop(StoppointCallbackContext *context) { return false; };
- virtual bool ShouldStop(StoppointCallbackContext* context,
- BreakpointLocationCollection &stopping_bp_locs) { return false; };
+ virtual bool ShouldStop(StoppointCallbackContext *context,
+ BreakpointLocationCollection &stopping_bp_locs) {
+ return false;
+ };
virtual void Dump(Stream* stream) const = 0;
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h
index c203e7f15d279..d29fd8126e0cc 100644
--- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedBreakpointInterface.h
@@ -27,14 +27,14 @@ class ScriptedBreakpointInterface : public ScriptedInterface {
virtual lldb::SearchDepth GetDepth() { return lldb::eSearchDepthModule; }
virtual std::optional<std::string> GetShortHelp() { return nullptr; }
/// WasHit returns the breakpoint location SP for the location that was "hit".
- virtual lldb::BreakpointLocationSP WasHit(lldb::StackFrameSP frame_sp,
- lldb::BreakpointLocationSP bp_loc_sp) {
- return LLDB_INVALID_BREAK_ID;
+ virtual lldb::BreakpointLocationSP
+ WasHit(lldb::StackFrameSP frame_sp, lldb::BreakpointLocationSP bp_loc_sp) {
+ return LLDB_INVALID_BREAK_ID;
}
- virtual std::optional<std::string>
- GetLocationDescription(lldb::BreakpointLocationSP bp_loc_sp,
- lldb::DescriptionLevel level) {
- return {};
+ virtual std::optional<std::string>
+ GetLocationDescription(lldb::BreakpointLocationSP bp_loc_sp,
+ lldb::DescriptionLevel level) {
+ return {};
}
};
} // namespace lldb_private
diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
index 554f8128344d9..6c0054a1ec1d1 100644
--- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -581,8 +581,8 @@ class ScriptInterpreter : public PluginInterface {
lldb::BreakpointSP
GetOpaqueTypeFromSBBreakpoint(const lldb::SBBreakpoint &breakpoint) const;
- lldb::BreakpointLocationSP
- GetOpaqueTypeFromSBBreakpointLocation(const lldb::SBBreakpointLocation &break_loc) const;
+ lldb::BreakpointLocationSP GetOpaqueTypeFromSBBreakpointLocation(
+ const lldb::SBBreakpointLocation &break_loc) const;
lldb::ProcessAttachInfoSP
GetOpaqueTypeFromSBAttachInfo(const lldb::SBAttachInfo &attach_info) const;
diff --git a/lldb/source/API/SBBreakpoint.cpp b/lldb/source/API/SBBreakpoint.cpp
index 93748dd46f69c..3777cfc7a61b3 100644
--- a/lldb/source/API/SBBreakpoint.cpp
+++ b/lldb/source/API/SBBreakpoint.cpp
@@ -567,8 +567,7 @@ SBError SBBreakpoint::AddLocation(SBAddress &address) {
return error;
}
-SBBreakpointLocation
-SBBreakpoint::AddFacadeLocation() {
+SBBreakpointLocation SBBreakpoint::AddFacadeLocation() {
BreakpointSP bkpt_sp = GetSP();
if (!bkpt_sp) {
return {};
diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp
index d6d2f8aa17c19..b665bfc4c47b9 100644
--- a/lldb/source/Breakpoint/Breakpoint.cpp
+++ b/lldb/source/Breakpoint/Breakpoint.cpp
@@ -61,7 +61,8 @@ Breakpoint::Breakpoint(Target &new_target, const Breakpoint &source_bp)
Breakpoint::~Breakpoint() {
for (BreakpointLocationSP location_sp : m_locations.BreakpointLocations())
location_sp->SetInvalid();
- for (BreakpointLocationSP location_sp : m_facade_locations.BreakpointLocations())
+ for (BreakpointLocationSP location_sp :
+ m_facade_locations.BreakpointLocations())
location_sp->SetInvalid();
}
@@ -309,14 +310,15 @@ BreakpointLocationSP Breakpoint::AddLocation(const Address &addr,
BreakpointLocationSP Breakpoint::AddFacadeLocation() {
size_t next_id = m_facade_locations.GetSize() + 1;
- BreakpointLocationSP break_loc_sp
- = std::make_shared<BreakpointLocation>(next_id, *this);
+ BreakpointLocationSP break_loc_sp =
+ std::make_shared<BreakpointLocation>(next_id, *this);
break_loc_sp->m_is_facade = true;
m_facade_locations.Add(break_loc_sp);
return break_loc_sp;
}
-BreakpointLocationSP Breakpoint::GetFacadeLocationByID(lldb::break_id_t loc_id) {
+BreakpointLocationSP
+Breakpoint::GetFacadeLocationByID(lldb::break_id_t loc_id) {
return m_facade_locations.GetByIndex(loc_id - 1);
}
@@ -328,13 +330,15 @@ break_id_t Breakpoint::FindLocationIDByAddress(const Address &addr) {
return m_locations.FindIDByAddress(addr);
}
-BreakpointLocationSP Breakpoint::FindLocationByID(break_id_t bp_loc_id, bool use_facade) {
+BreakpointLocationSP Breakpoint::FindLocationByID(break_id_t bp_loc_id,
+ bool use_facade) {
if (use_facade && m_facade_locations.GetSize())
return GetFacadeLocationByID(bp_loc_id);
return m_locations.FindByID(bp_loc_id);
}
-BreakpointLocationSP Breakpoint::GetLocationAtIndex(size_t index, bool use_facade) {
+BreakpointLocationSP Breakpoint::GetLocationAtIndex(size_t index,
+ bool use_facade) {
if (use_facade && m_facade_locations.GetSize() > 0)
return m_facade_locations.GetByIndex(index);
return m_locations.GetByIndex(index);
@@ -904,13 +908,13 @@ bool Breakpoint::HasResolvedLocations() const {
return GetNumResolvedLocations() > 0;
}
-size_t Breakpoint::GetNumLocations(bool use_facade) const {
+size_t Breakpoint::GetNumLocations(bool use_facade) const {
if (use_facade) {
size_t num_facade_locs = m_facade_locations.GetSize();
if (num_facade_locs > 0)
return num_facade_locs;
}
- return m_locations.GetSize();
+ return m_locations.GetSize();
}
void Breakpoint::AddName(llvm::StringRef new_name) {
@@ -936,14 +940,14 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level,
s->Printf("Kind: %s\n", GetBreakpointKind());
}
- bool show_both_types = level == eDescriptionLevelVerbose
- && HasFacadeLocations() && show_locations;
+ bool show_both_types = level == eDescriptionLevelVerbose &&
+ HasFacadeLocations() && show_locations;
uint8_t display_mask = eDisplayFacade;
if (show_both_types)
display_mask |= eDisplayHeader;
-
+
GetDescriptionForType(s, level, display_mask, show_locations);
-
+
if (show_both_types) {
display_mask = eDisplayReal | eDisplayHeader;
GetDescriptionForType(s, level, display_mask, show_locations);
@@ -954,9 +958,10 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level,
GetTarget().GetDebugger().GetDisabledAnsiSuffix())
.c_str());
}
-
+
void Breakpoint::GetDescriptionForType(Stream *s, lldb::DescriptionLevel level,
- uint8_t display_type, bool show_locations) {
+ uint8_t display_type,
+ bool show_locations) {
bool use_facade = (display_type & eDisplayFacade) != 0;
const size_t num_locations = GetNumLocations(use_facade);
const size_t num_resolved_locations = GetNumResolvedLocations(use_facade);
@@ -1052,7 +1057,6 @@ void Breakpoint::GetDescriptionForType(Stream *s, lldb::DescriptionLevel level,
}
s->IndentLess();
}
-
}
void Breakpoint::GetResolverDescription(Stream *s) {
diff --git a/lldb/source/Breakpoint/BreakpointLocation.cpp b/lldb/source/Breakpoint/BreakpointLocation.cpp
index 829ed03392999..2505fb26e8d45 100644
--- a/lldb/source/Breakpoint/BreakpointLocation.cpp
+++ b/lldb/source/Breakpoint/BreakpointLocation.cpp
@@ -381,11 +381,12 @@ bool BreakpointLocation::ValidForThisThread(Thread &thread) {
.GetThreadSpecNoCreate());
}
-BreakpointLocationSP BreakpointLocation::WasHit(StoppointCallbackContext *context)
-{
+BreakpointLocationSP
+BreakpointLocation::WasHit(StoppointCallbackContext *context) {
// Only the BreakpointResolverScripted provides WasHit.
BreakpointResolverSP resolver_sp = GetBreakpoint().GetResolver();
- BreakpointResolverScripted *scripted = llvm::dyn_cast<BreakpointResolverScripted>(resolver_sp.get());
+ BreakpointResolverScripted *scripted =
+ llvm::dyn_cast<BreakpointResolverScripted>(resolver_sp.get());
if (!scripted)
return shared_from_this();
@@ -393,7 +394,8 @@ BreakpointLocationSP BreakpointLocation::WasHit(StoppointCallbackContext *contex
if (!frame_sp)
return shared_from_this();
- BreakpointLocationSP return_loc_sp = scripted->WasHit(frame_sp, shared_from_this());
+ BreakpointLocationSP return_loc_sp =
+ scripted->WasHit(frame_sp, shared_from_this());
// If this is a facade location, then we won't have bumped its hit count
// while processing the original location hit. Do so here. We don't need
// to bump the breakpoint's hit count, however, since hitting the real
@@ -401,10 +403,10 @@ BreakpointLocationSP BreakpointLocation::WasHit(StoppointCallbackContext *contex
// Also we have to check the enabled state here, since we would never have
// gotten here with a real location...
if (return_loc_sp && return_loc_sp->IsFacade()) {
- if (return_loc_sp->IsEnabled())
- return_loc_sp->m_hit_counter.Increment();
- else
- return {};
+ if (return_loc_sp->IsEnabled())
+ return_loc_sp->m_hit_counter.Increment();
+ else
+ return {};
}
return return_loc_sp;
}
@@ -414,8 +416,8 @@ BreakpointLocationSP BreakpointLocation::WasHit(StoppointCallbackContext *contex
// here, since if the breakpoint is not for this thread, then the event won't
// even get reported, so the check is redundant.
-bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context,
- lldb::BreakpointLocationSP &facade_loc_sp) {
+bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context,
+ lldb::BreakpointLocationSP &facade_loc_sp) {
bool should_stop = true;
Log *log = GetLog(LLDBLog::Breakpoints);
@@ -426,7 +428,7 @@ bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context,
// Next check WasHit:
BreakpointLocationSP loc_hit_sp = WasHit(context);
-
+
if (!loc_hit_sp) {
// We bump the hit counts in StopInfoBreakpoint::ShouldStopSynchronous,
// before we call into each location's ShouldStop. So we need to undo
@@ -434,7 +436,7 @@ bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context,
UndoBumpHitCount();
return false;
}
-
+
// If the location hit was not us, it was a facade location, in which case
// we should use the facade location's callbacks, etc. Those will all be
// run in the asynchronous phase, so for now we just have to record the fact
@@ -494,7 +496,7 @@ lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const {
llvm::Error BreakpointLocation::ResolveBreakpointSite() {
// This might be a facade location, which doesn't have an address.
// In that case, don't attempt to make a site.
- if (m_bp_site_sp || IsFacade())
+ if (m_bp_site_sp || IsFacade())
return llvm::Error::success();
Process *process = m_owner.GetTarget().GetProcessSP().get();
@@ -547,15 +549,15 @@ llvm::Error BreakpointLocation::ClearBreakpointSite() {
void BreakpointLocation::GetDescription(Stream *s,
lldb::DescriptionLevel level) {
SymbolContext sc;
-
+
// If this is a scripted breakpoint, give it a chance to describe its
// locations:
std::optional<std::string> scripted_opt;
BreakpointResolverSP resolver_sp = GetBreakpoint().GetResolver();
- BreakpointResolverScripted *scripted =
+ BreakpointResolverScripted *scripted =
llvm::dyn_cast<BreakpointResolverScripted>(resolver_sp.get());
if (scripted)
- scripted_opt = scripted->GetLocationDescription(shared_from_this(), level);
+ scripted_opt = scripted->GetLocationDescription(shared_from_this(), level);
bool is_scripted_desc = scripted_opt.has_value();
@@ -694,10 +696,10 @@ void BreakpointLocation::GetDescription(Stream *s,
// If they don't add any scripted locations, we shouldn't consider them
// resolved.
bool is_resolved = is_scripted_desc || IsResolved();
- // A scripted breakpoint might be resolved but not have a site. Be sure to
+ // A scripted breakpoint might be resolved but not have a site. Be sure to
// check for that.
- bool is_hardware = !is_scripted_desc && IsResolved() && m_bp_site_sp
- && m_bp_site_sp->IsHardware();
+ bool is_hardware = !is_scripted_desc && IsResolved() && m_bp_site_sp &&
+ m_bp_site_sp->IsHardware();
if (level == lldb::eDescriptionLevelVerbose) {
s->EOL();
diff --git a/lldb/source/Breakpoint/BreakpointLocationList.cpp b/lldb/source/Breakpoint/BreakpointLocationList.cpp
index 5a791d4364641..ea431aa3bb953 100644
--- a/lldb/source/Breakpoint/BreakpointLocationList.cpp
+++ b/lldb/source/Breakpoint/BreakpointLocationList.cpp
@@ -32,9 +32,9 @@ BreakpointLocationList::Create(const Address &addr,
std::lock_guard<std::recursive_mutex> guard(m_mutex);
// The location ID is just the size of the location list + 1
lldb::break_id_t bp_loc_id = ++m_next_id;
- BreakpointLocationSP bp_loc_sp(new
- BreakpointLocation(bp_loc_id, m_owner, addr, LLDB_INVALID_THREAD_ID,
- resolve_indirect_symbols));
+ BreakpointLocationSP bp_loc_sp(
+ new BreakpointLocation(bp_loc_id, m_owner, addr, LLDB_INVALID_THREAD_ID,
+ resolve_indirect_symbols));
m_locations.push_back(bp_loc_sp);
m_address_to_location[addr] = bp_loc_sp;
return bp_loc_sp;
diff --git a/lldb/source/Breakpoint/BreakpointResolverScripted.cpp b/lldb/source/Breakpoint/BreakpointResolverScripted.cpp
index b1e45d761735b..a4969a07b396b 100644
--- a/lldb/source/Breakpoint/BreakpointResolverScripted.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverScripted.cpp
@@ -160,17 +160,17 @@ void BreakpointResolverScripted::GetDescription(Stream *s) {
s->Printf("python class = %s", m_class_name.c_str());
}
-std::optional<std::string>
-BreakpointResolverScripted::GetLocationDescription(
+std::optional<std::string> BreakpointResolverScripted::GetLocationDescription(
lldb::BreakpointLocationSP bp_loc_sp, lldb::DescriptionLevel level) {
CreateImplementationIfNeeded(GetBreakpoint());
- if (m_interface_sp)
+ if (m_interface_sp)
return m_interface_sp->GetLocationDescription(bp_loc_sp, level);
return {};
}
lldb::BreakpointLocationSP
-BreakpointResolverScripted::WasHit(lldb::StackFrameSP frame_sp, lldb::BreakpointLocationSP bp_loc_sp) {
+BreakpointResolverScripted::WasHit(lldb::StackFrameSP frame_sp,
+ lldb::BreakpointLocationSP bp_loc_sp) {
if (m_interface_sp)
return m_interface_sp->WasHit(frame_sp, bp_loc_sp);
diff --git a/lldb/source/Breakpoint/BreakpointSite.cpp b/lldb/source/Breakpoint/BreakpointSite.cpp
index 52100b91de09c..fd7666be6b1bf 100644
--- a/lldb/source/Breakpoint/BreakpointSite.cpp
+++ b/lldb/source/Breakpoint/BreakpointSite.cpp
@@ -45,8 +45,9 @@ break_id_t BreakpointSite::GetNextID() {
// RETURNS - true if we should stop at this breakpoint, false if we
// should continue.
-bool BreakpointSite::ShouldStop(StoppointCallbackContext *context,
- BreakpointLocationCollection &stopping_bp_locs) {
+bool BreakpointSite::ShouldStop(
+ StoppointCallbackContext *context,
+ BreakpointLocationCollection &stopping_bp_locs) {
m_hit_counter.Increment();
// ShouldStop can do a lot of work, and might even come back and hit
// this breakpoint site again. So don't hold the m_constituents_mutex the
diff --git a/lldb/source/Interpreter/ScriptInterpreter.cpp b/lldb/source/Interpreter/ScriptInterpreter.cpp
index 51475db27269b..b5ad85d265314 100644
--- a/lldb/source/Interpreter/ScriptInterpreter.cpp
+++ b/lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -81,7 +81,8 @@ lldb::BreakpointSP ScriptInterpreter::GetOpaqueTypeFromSBBreakpoint(
return breakpoint.m_opaque_wp.lock();
}
-lldb::BreakpointLocationSP ScriptInterpreter::GetOpaqueTypeFromSBBreakpointLocation(
+lldb::BreakpointLocationSP
+ScriptInterpreter::GetOpaqueTypeFromSBBreakpointLocation(
const lldb::SBBreakpointLocation &break_loc) const {
return break_loc.m_opaque_wp.lock();
}
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp
index 0c6d23b108fa1..c9bb38d213c99 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.cpp
@@ -81,11 +81,11 @@ std::optional<std::string> ScriptedBreakpointPythonInterface::GetShortHelp() {
return obj->GetAsString()->GetValue().str();
}
-lldb::BreakpointLocationSP
-ScriptedBreakpointPythonInterface::WasHit(lldb::StackFrameSP frame_sp, lldb::BreakpointLocationSP bp_loc_sp) {
+lldb::BreakpointLocationSP ScriptedBreakpointPythonInterface::WasHit(
+ lldb::StackFrameSP frame_sp, lldb::BreakpointLocationSP bp_loc_sp) {
Status py_error;
- lldb::BreakpointLocationSP loc_sp
- = Dispatch<lldb::BreakpointLocationSP>("was_hit", py_error, frame_sp, bp_loc_sp);
+ lldb::BreakpointLocationSP loc_sp = Dispatch<lldb::BreakpointLocationSP>(
+ "was_hit", py_error, frame_sp, bp_loc_sp);
if (py_error.Fail())
return bp_loc_sp;
@@ -93,12 +93,12 @@ ScriptedBreakpointPythonInterface::WasHit(lldb::StackFrameSP frame_sp, lldb::Bre
return loc_sp;
}
-std::optional<std::string>
+std::optional<std::string>
ScriptedBreakpointPythonInterface::GetLocationDescription(
- lldb::BreakpointLocationSP bp_loc_sp,
- lldb::DescriptionLevel level) {
+ lldb::BreakpointLocationSP bp_loc_sp, lldb::DescriptionLevel level) {
Status error;
- StructuredData::ObjectSP obj = Dispatch("get_location_description", error, bp_loc_sp, level);
+ StructuredData::ObjectSP obj =
+ Dispatch("get_location_description", error, bp_loc_sp, level);
if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
error))
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h
index b8c1219279876..72da0a195ee01 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedBreakpointPythonInterface.h
@@ -36,12 +36,12 @@ class ScriptedBreakpointPythonInterface : public ScriptedBreakpointInterface,
bool ResolverCallback(SymbolContext sym_ctx) override;
lldb::SearchDepth GetDepth() override;
std::optional<std::string> GetShortHelp() override;
- lldb::BreakpointLocationSP WasHit(lldb::StackFrameSP frame_sp,
- lldb::BreakpointLocationSP bp_loc_sp) override;
- virtual std::optional<std::string>
- GetLocationDescription(lldb::BreakpointLocationSP bp_loc_sp,
- lldb::DescriptionLevel level) override;
-
+ lldb::BreakpointLocationSP
+ WasHit(lldb::StackFrameSP frame_sp,
+ lldb::BreakpointLocationSP bp_loc_sp) override;
+ virtual std::optional<std::string>
+ GetLocationDescription(lldb::BreakpointLocationSP bp_loc_sp,
+ lldb::DescriptionLevel level) override;
static void Initialize();
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
index cda8185ef0a17..4fdf2b12a5500 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.cpp
@@ -141,14 +141,16 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::BreakpointSP>(
template <>
lldb::BreakpointLocationSP
-ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::BreakpointLocationSP>(
- python::PythonObject &p, Status &error) {
- lldb::SBBreakpointLocation *sb_break_loc = reinterpret_cast<lldb::SBBreakpointLocation *>(
- python::LLDBSWIGPython_CastPyObjectToSBBreakpointLocation(p.get()));
+ScriptedPythonInterface::ExtractValueFromPythonObject<
+ lldb::BreakpointLocationSP>(python::PythonObject &p, Status &error) {
+ lldb::SBBreakpointLocation *sb_break_loc =
+ reinterpret_cast<lldb::SBBreakpointLocation *>(
+ python::LLDBSWIGPython_CastPyObjectToSBBreakpointLocation(p.get()));
if (!sb_break_loc) {
error = Status::FromErrorStringWithFormat(
- "Couldn't cast lldb::SBBreakpointLocation to lldb::BreakpointLocationSP.");
+ "Couldn't cast lldb::SBBreakpointLocation to "
+ "lldb::BreakpointLocationSP.");
return nullptr;
}
@@ -225,20 +227,20 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<
template <>
lldb::DescriptionLevel
-ScriptedPythonInterface::ExtractValueFromPythonObject<
- lldb::DescriptionLevel>(python::PythonObject &p, Status &error) {
- lldb::DescriptionLevel ret_val = lldb::eDescriptionLevelBrief;
- llvm::Expected<unsigned long long> unsigned_or_err = p.AsUnsignedLongLong();
- if (!unsigned_or_err) {
- error = (Status::FromError(unsigned_or_err.takeError()));
- return ret_val;
- }
- unsigned long long unsigned_val = *unsigned_or_err;
- if (unsigned_val >= lldb::DescriptionLevel::kNumDescriptionLevels) {
- error = Status("value too large for lldb::DescriptionLevel.");
- return ret_val;
- }
- return static_cast<lldb::DescriptionLevel>(unsigned_val);
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DescriptionLevel>(
+ python::PythonObject &p, Status &error) {
+ lldb::DescriptionLevel ret_val = lldb::eDescriptionLevelBrief;
+ llvm::Expected<unsigned long long> unsigned_or_err = p.AsUnsignedLongLong();
+ if (!unsigned_or_err) {
+ error = (Status::FromError(unsigned_or_err.takeError()));
+ return ret_val;
+ }
+ unsigned long long unsigned_val = *unsigned_or_err;
+ if (unsigned_val >= lldb::DescriptionLevel::kNumDescriptionLevels) {
+ error = Status("value too large for lldb::DescriptionLevel.");
+ return ret_val;
+ }
+ return static_cast<lldb::DescriptionLevel>(unsigned_val);
}
#endif
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
index 57d22d44e565e..2335b2ef0f171 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
@@ -597,8 +597,8 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::BreakpointSP>(
template <>
lldb::BreakpointLocationSP
-ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::BreakpointLocationSP>(
- python::PythonObject &p, Status &error);
+ScriptedPythonInterface::ExtractValueFromPythonObject<
+ lldb::BreakpointLocationSP>(python::PythonObject &p, Status &error);
template <>
lldb::ProcessAttachInfoSP ScriptedPythonInterface::ExtractValueFromPythonObject<
@@ -625,8 +625,8 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<
template <>
lldb::DescriptionLevel
-ScriptedPythonInterface::ExtractValueFromPythonObject<
- lldb::DescriptionLevel>(python::PythonObject &p, Status &error);
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DescriptionLevel>(
+ python::PythonObject &p, Status &error);
} // namespace lldb_private
diff --git a/lldb/source/Target/StopInfo.cpp b/lldb/source/Target/StopInfo.cpp
index b864159ba7471..7fa1fc5d71f13 100644
--- a/lldb/source/Target/StopInfo.cpp
+++ b/lldb/source/Target/StopInfo.cpp
@@ -157,7 +157,8 @@ class StopInfoBreakpoint : public StopInfo {
ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
StoppointCallbackContext context(event_ptr, exe_ctx, true);
bp_site_sp->BumpHitCounts();
- m_should_stop = bp_site_sp->ShouldStop(&context, m_async_stopped_locs);
+ m_should_stop =
+ bp_site_sp->ShouldStop(&context, m_async_stopped_locs);
} else {
Log *log = GetLog(LLDBLog::Process);
@@ -345,8 +346,7 @@ class StopInfoBreakpoint : public StopInfo {
// local list. That way if one of the breakpoint actions changes the
// site, then we won't be operating on a bad list.
BreakpointLocationCollection site_locations;
- size_t num_constituents =
- m_async_stopped_locs.GetSize();
+ size_t num_constituents = m_async_stopped_locs.GetSize();
if (num_constituents == 0) {
m_should_stop = true;
@@ -445,7 +445,7 @@ class StopInfoBreakpoint : public StopInfo {
// breakpoints, and the locations don't keep their constituents alive.
// I'm just sticking the BreakpointSP's in a vector since I'm only
// using it to locally increment their retain counts.
-
+
// We are holding onto the breakpoint locations that were hit
// by this stop info between the "synchonous" ShouldStop and now.
// But an intervening action might have deleted one of the breakpoints
@@ -465,8 +465,7 @@ class StopInfoBreakpoint : public StopInfo {
size_t num_valid_locs = valid_locs.GetSize();
for (size_t j = 0; j < num_valid_locs; j++) {
- lldb::BreakpointLocationSP bp_loc_sp
- = valid_locs.GetByIndex(j);
+ lldb::BreakpointLocationSP bp_loc_sp = valid_locs.GetByIndex(j);
StreamString loc_desc;
if (log) {
bp_loc_sp->GetDescription(&loc_desc, eDescriptionLevelBrief);
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/TestWasHit.py b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/TestWasHit.py
index de178f5b04fc7..2e176239facf0 100644
--- a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/TestWasHit.py
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/TestWasHit.py
@@ -33,7 +33,7 @@ def import_resolver_script(self):
self.runCmd(command)
def make_extra_args(self, sym_name, num_locs, loc_to_miss):
- return f' -k symbol -v {sym_name} -k num_locs -v {num_locs} -k loc_to_miss -v {loc_to_miss} '
+ return f" -k symbol -v {sym_name} -k num_locs -v {num_locs} -k loc_to_miss -v {loc_to_miss} "
def do_test(self):
"""This reads in a python file and sets a breakpoint using it."""
@@ -41,7 +41,9 @@ def do_test(self):
target = self.make_target_and_import()
extra_args = self.make_extra_args("stop_symbol", 4, 2)
- bkpt_no = lldbutil.run_break_set_by_script(self, "bkpt_resolver.FacadeExample", extra_args, 4)
+ bkpt_no = lldbutil.run_break_set_by_script(
+ self, "bkpt_resolver.FacadeExample", extra_args, 4
+ )
# Make sure the help text shows up in the "break list" output:
self.expect(
@@ -52,34 +54,49 @@ def do_test(self):
bkpt = target.FindBreakpointByID(bkpt_no)
self.assertTrue(bkpt.IsValid(), "Found the right breakpoint")
-
+
# Now continue. We should hit locations 1, 3 and 4:
- (target, process, thread, bkpt) = lldbutil.run_to_breakpoint_do_run(self, target, bkpt)
+ (target, process, thread, bkpt) = lldbutil.run_to_breakpoint_do_run(
+ self, target, bkpt
+ )
# This location should be bkpt_no.1:
- self.assertEqual(thread.stop_reason_data[0], bkpt_no, "Hit the right breakpoint")
+ self.assertEqual(
+ thread.stop_reason_data[0], bkpt_no, "Hit the right breakpoint"
+ )
self.assertEqual(thread.stop_reason_data[1], 1, "First location hit is 1")
for loc in [3, 4]:
process.Continue()
- self.assertEqual(thread.stop_reason, lldb.eStopReasonBreakpoint, "Hit breakpoint")
- self.assertEqual(thread.stop_reason_data[0], bkpt_no, "Hit the right breakpoint")
- self.assertEqual(thread.stop_reason_data[1], loc, f"Hit the right location: {loc}")
+ self.assertEqual(
+ thread.stop_reason, lldb.eStopReasonBreakpoint, "Hit breakpoint"
+ )
+ self.assertEqual(
+ thread.stop_reason_data[0], bkpt_no, "Hit the right breakpoint"
+ )
+ self.assertEqual(
+ thread.stop_reason_data[1], loc, f"Hit the right location: {loc}"
+ )
# At this point we should have hit three of the four locations, and not location 1.2.
# Check that that is true, and that the descriptions for the location are the ones
# the resolver provided.
self.assertEqual(bkpt.hit_count, 3, "Hit three locations")
- for loc_id in range(1,4):
+ for loc_id in range(1, 4):
bkpt_loc = bkpt.FindLocationByID(loc_id)
self.assertTrue(bkpt_loc.IsValid(), f"{loc_id} was invalid.")
if loc_id != 2:
- self.assertEqual(bkpt_loc.hit_count, 1, f"Loc {loc_id} hit count was wrong")
+ self.assertEqual(
+ bkpt_loc.hit_count, 1, f"Loc {loc_id} hit count was wrong"
+ )
else:
self.assertEqual(bkpt_loc.hit_count, 0, "We didn't skip loc 2")
stream = lldb.SBStream()
- self.assertTrue(bkpt_loc.GetDescription(stream, lldb.eDescriptionLevelFull),
- f"Didn't get description for {loc_id}")
- self.assertIn(f"Location index: {loc_id}", stream.GetData(),
- f"Wrong desciption for {loc_id}")
-
-
+ self.assertTrue(
+ bkpt_loc.GetDescription(stream, lldb.eDescriptionLevelFull),
+ f"Didn't get description for {loc_id}",
+ )
+ self.assertIn(
+ f"Location index: {loc_id}",
+ stream.GetData(),
+ f"Wrong desciption for {loc_id}",
+ )
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/bkpt_resolver.py b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/bkpt_resolver.py
index 004ee18513f2f..b8cc3fb8eb07e 100644
--- a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/bkpt_resolver.py
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/bkpt_resolver.py
@@ -1,5 +1,6 @@
import lldb
+
class FacadeExample:
def __init__(self, bkpt, extra_args, dict):
self.bkpt = bkpt
@@ -11,7 +12,9 @@ def __init__(self, bkpt, extra_args, dict):
self.sym_name = extra_args.GetValueForKey("symbol").GetStringValue(100)
self.num_locs = extra_args.GetValueForKey("num_locs").GetIntegerValue(5)
- self.loc_to_miss = extra_args.GetValueForKey("loc_to_miss").GetIntegerValue(10000)
+ self.loc_to_miss = extra_args.GetValueForKey("loc_to_miss").GetIntegerValue(
+ 10000
+ )
def __callback__(self, sym_ctx):
self.base_sym = sym_ctx.module.FindSymbol(self.sym_name, lldb.eSymbolTypeCode)
@@ -19,21 +22,23 @@ def __callback__(self, sym_ctx):
self.bkpt.AddLocation(self.base_sym.GetStartAddress())
# Locations are 1 based, so to keep things simple, I'm making
# the array holding locations 1 based as well:
- self.facade_locs_desc.append("This is the zero index, you shouldn't see this")
+ self.facade_locs_desc.append(
+ "This is the zero index, you shouldn't see this"
+ )
self.facade_locs.append(None)
for i in range(1, self.num_locs + 1):
self.facade_locs_desc.append(f"Location index: {i}")
self.facade_locs.append(self.bkpt.AddFacadeLocation())
-
+
def get_short_help(self):
return f"I am a facade resolver - sym: {self.sym_name} - num_locs: {self.num_locs} - locs_to_miss: {self.loc_to_miss}"
def was_hit(self, frame, bp_loc):
tmp_loc = self.cur_facade_loc
- self.cur_facade_loc = (self.cur_facade_loc + 1)
+ self.cur_facade_loc = self.cur_facade_loc + 1
if self.cur_facade_loc == 5:
- self.cur_facade_loc = 1
+ self.cur_facade_loc = 1
if tmp_loc == self.loc_to_miss:
return None
@@ -42,4 +47,3 @@ def was_hit(self, frame, bp_loc):
def get_location_description(self, bp_loc, desc_level):
return self.facade_locs_desc[bp_loc.id]
-
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/main.c b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/main.c
index 762553109f7f7..b8f977e493513 100644
--- a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/main.c
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/was_hit/main.c
@@ -1,15 +1,12 @@
#include <stdio.h>
-int
-stop_symbol() {
+int stop_symbol() {
static int s_cnt = 0;
printf("I am in the stop symbol: %d\n", s_cnt++);
return s_cnt;
}
-int
-main()
-{
+int main() {
for (int i = 0; i < 100; i++) {
stop_symbol();
}
More information about the lldb-commits
mailing list