//===-- BreakpointLocation.h ------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef liblldb_BreakpointLocation_h_ #define liblldb_BreakpointLocation_h_ #include #include #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Breakpoint/StoppointLocation.h" #include "lldb/Core/Address.h" #include "lldb/Utility/UserID.h" #include "lldb/lldb-private.h" namespace lldb_private { /// \class BreakpointLocation BreakpointLocation.h /// "lldb/Breakpoint/BreakpointLocation.h" Class that manages one unique (by /// address) instance of a logical breakpoint. /// General Outline: /// A breakpoint location is defined by the breakpoint that produces it, /// and the address that resulted in this particular instantiation. Each /// breakpoint location also may have a breakpoint site if its address has /// been loaded into the program. Finally it has a settable options object. /// /// FIXME: Should we also store some fingerprint for the location, so /// we can map one location to the "equivalent location" on rerun? This would /// be useful if you've set options on the locations. class BreakpointLocation : public std::enable_shared_from_this, public StoppointLocation { public: ~BreakpointLocation() override; /// Gets the load address for this breakpoint location \return /// Returns breakpoint location load address, \b /// LLDB_INVALID_ADDRESS if not yet set. lldb::addr_t GetLoadAddress() const override; /// Gets the Address for this breakpoint location \return /// Returns breakpoint location Address. Address &GetAddress(); /// Gets the Breakpoint that created this breakpoint location \return /// Returns the owning breakpoint. Breakpoint &GetBreakpoint(); Target &GetTarget(); /// 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. /// /// \return /// \b true if this breakpoint location thinks we should stop, /// \b false otherwise. bool ShouldStop(StoppointCallbackContext *context) override; // The next section deals with various breakpoint options. /// If \a enabled is \b true, enable the breakpoint, if \b false disable it. void SetEnabled(bool enabled); /// Check the Enable/Disable state. /// /// \return /// \b true if the breakpoint is enabled, \b false if disabled. bool IsEnabled() const; /// If \a auto_continue is \b true, set the breakpoint to continue when hit. void SetAutoContinue(bool auto_continue); /// Check the AutoContinue state. /// /// \return /// \b true if the breakpoint is set to auto-continue, \b false if not. bool IsAutoContinue() const; /// Return the current Ignore Count. /// /// \return /// The number of breakpoint hits to be ignored. uint32_t GetIgnoreCount(); /// Set the breakpoint to ignore the next \a count breakpoint hits. /// /// \param[in] n /// The number of breakpoint hits to ignore. void SetIgnoreCount(uint32_t n); /// Set the callback action invoked when the breakpoint is hit. /// /// The callback will return a bool indicating whether the target should /// stop at this breakpoint or not. /// /// \param[in] callback /// The method that will get called when the breakpoint is hit. /// /// \param[in] callback_baton_sp /// A shared pointer to a Baton that provides the void * needed /// for the callback. /// /// \see lldb_private::Baton void SetCallback(BreakpointHitCallback callback, const lldb::BatonSP &callback_baton_sp, bool is_synchronous); void SetCallback(BreakpointHitCallback callback, void *baton, bool is_synchronous); void ClearCallback(); /// Set the breakpoint location's condition. /// /// \param[in] condition /// The condition expression to evaluate when the breakpoint is hit. void SetCondition(const char *condition); /// Return a pointer to the text of the condition expression. /// /// \return /// A pointer to the condition expression text, or nullptr if no // condition has been set. const char *GetConditionText(size_t *hash = nullptr) const; bool ConditionSaysStop(ExecutionContext &exe_ctx, Status &error); /// Set the valid thread to be checked when the breakpoint is hit. /// /// \param[in] thread_id /// If this thread hits the breakpoint, we stop, otherwise not. void SetThreadID(lldb::tid_t thread_id); lldb::tid_t GetThreadID(); void SetThreadIndex(uint32_t index); uint32_t GetThreadIndex() const; void SetThreadName(const char *thread_name); const char *GetThreadName() const; void SetQueueName(const char *queue_name); const char *GetQueueName() const; // The next section deals with this location's breakpoint sites. /// Try to resolve the breakpoint site for this location. /// /// \return /// \b true if we were successful at setting a breakpoint site, /// \b false otherwise. bool ResolveBreakpointSite(); /// Clear this breakpoint location's breakpoint site - for instance when /// disabling the breakpoint. /// /// \return /// \b true if there was a breakpoint site to be cleared, \b false /// otherwise. bool ClearBreakpointSite(); /// Return whether this breakpoint location has a breakpoint site. \return /// \b true if there was a breakpoint site for this breakpoint /// location, \b false otherwise. bool IsResolved() const; lldb::BreakpointSiteSP GetBreakpointSite() const; // The next section are generic report functions. /// Print a description of this breakpoint location to the stream \a s. /// /// \param[in] s /// The stream to which to print the description. /// /// \param[in] level /// The description level that indicates the detail level to /// provide. /// /// \see lldb::DescriptionLevel void GetDescription(Stream *s, lldb::DescriptionLevel level); /// Standard "Dump" method. At present it does nothing. void Dump(Stream *s) const override; /// Use this to set location specific breakpoint options. /// /// It will create a copy of the containing breakpoint's options if that /// hasn't been done already /// /// \return /// A pointer to the breakpoint options. BreakpointOptions *GetLocationOptions(); /// Use this to access breakpoint options from this breakpoint location. /// This will return the options that have a setting for the specified /// BreakpointOptions kind. /// /// \param[in] kind /// The particular option you are looking up. /// \return /// A pointer to the containing breakpoint's options if this /// location doesn't have its own copy. const BreakpointOptions *GetOptionsSpecifyingKind( BreakpointOptions::OptionKind kind) const; bool ValidForThisThread(Thread *thread); /// Invoke the callback action when the breakpoint is hit. /// /// Meant to be used by the BreakpointLocation class. /// /// \param[in] context /// Described the breakpoint event. /// /// \return /// \b true if the target should stop at this breakpoint and \b /// false not. bool InvokeCallback(StoppointCallbackContext *context); /// Returns whether we should resolve Indirect functions in setting the /// breakpoint site for this location. /// /// \return /// \b true if the breakpoint SITE for this location should be set on the /// resolved location for Indirect functions. bool ShouldResolveIndirectFunctions() { return m_should_resolve_indirect_functions; } /// Returns whether the address set in the breakpoint site for this location /// was found by resolving an indirect symbol. /// /// \return /// \b true or \b false as given in the description above. bool IsIndirect() { return m_is_indirect; } void SetIsIndirect(bool is_indirect) { m_is_indirect = is_indirect; } /// Returns whether the address set in the breakpoint location was re-routed /// to the target of a re-exported symbol. /// /// \return /// \b true or \b false as given in the description above. bool IsReExported() { return m_is_reexported; } void SetIsReExported(bool is_reexported) { m_is_reexported = is_reexported; } /// Returns whether the two breakpoint locations might represent "equivalent /// locations". This is used when modules changed to determine if a Location /// in the old module might be the "same as" the input location. /// /// \param[in] location /// The location to compare against. /// /// \return /// \b true or \b false as given in the description above. bool EquivalentToLocation(BreakpointLocation &location); 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 /// The breakpoint site we are setting for this location. /// /// \return /// \b true if we were successful at setting the breakpoint site, /// \b false otherwise. bool SetBreakpointSite(lldb::BreakpointSiteSP &bp_site_sp); void DecrementIgnoreCount(); bool IgnoreCountShouldStop(); private: void SwapLocation(lldb::BreakpointLocationSP swap_from); void BumpHitCount(); void UndoBumpHitCount(); // Constructors and Destructors // // Only the Breakpoint can make breakpoint locations, and it owns them. /// Constructor. /// /// \param[in] owner /// A back pointer to the breakpoint that owns this location. /// /// \param[in] addr /// The Address defining this location. /// /// \param[in] tid /// The thread for which this breakpoint location is valid, or /// LLDB_INVALID_THREAD_ID if it is valid for all threads. /// /// \param[in] hardware /// \b true if a hardware breakpoint is requested. BreakpointLocation(lldb::break_id_t bid, Breakpoint &owner, const Address &addr, lldb::tid_t tid, bool hardware, bool check_for_resolver = true); // Data members: bool m_being_created; bool m_should_resolve_indirect_functions; bool m_is_reexported; bool m_is_indirect; Address m_address; ///< The address defining this location. Breakpoint &m_owner; ///< The breakpoint that produced this object. std::unique_ptr m_options_up; ///< Breakpoint options /// pointer, nullptr if we're /// using our breakpoint's /// options. lldb::BreakpointSiteSP m_bp_site_sp; ///< Our breakpoint site (it may be ///shared by more than one location.) lldb::UserExpressionSP m_user_expression_sp; ///< The compiled expression to ///use in testing our condition. std::mutex m_condition_mutex; ///< Guards parsing and evaluation of the ///condition, which could be evaluated by /// multiple processes. size_t m_condition_hash; ///< For testing whether the condition source code ///changed. void SetShouldResolveIndirectFunctions(bool do_resolve) { m_should_resolve_indirect_functions = do_resolve; } void SendBreakpointLocationChangedEvent(lldb::BreakpointEventType eventKind); DISALLOW_COPY_AND_ASSIGN(BreakpointLocation); }; } // namespace lldb_private #endif // liblldb_BreakpointLocation_h_