bp_loc_hardware_breakpoint,
bp_loc_software_watchpoint,
bp_loc_hardware_watchpoint,
+ bp_loc_tracepoint,
bp_loc_other /* Miscellaneous... */
};
-class bp_location : public refcounted_object
+class bp_location : public refcounted_object, public intrusive_list_node<bp_location>
{
public:
- bp_location () = default;
-
/* Construct a bp_location with the type inferred from OWNER's
type. */
explicit bp_location (breakpoint *owner);
virtual ~bp_location () = default;
- /* Chain pointer to the next breakpoint location for
- the same parent breakpoint. */
- bp_location *next = NULL;
-
/* Type of this breakpoint location. */
bp_loc_type loc_type {};
/* The objfile the symbol or minimal symbol were found in. */
const struct objfile *objfile = NULL;
+
+ /* Return a string representation of the bp_location.
+ This is only meant to be used in debug messages. */
+ std::string to_string () const;
};
/* A policy class for bp_location reference counting. */
struct linespec_result *,
gdb::unique_xmalloc_ptr<char>,
gdb::unique_xmalloc_ptr<char>,
- enum bptype, enum bpdisp, int, int,
+ enum bptype, enum bpdisp, int, int, int,
int, int, int, int, unsigned);
};
extern bool target_exact_watchpoints;
-/* bp_location linked list range. */
-
-using bp_location_range = next_range<bp_location>;
+using bp_location_list = intrusive_list<bp_location>;
+using bp_location_iterator = bp_location_list::iterator;
+using bp_location_range = iterator_range<bp_location_iterator>;
/* Note that the ->silent field is not currently used by any commands
(though the code is in there if it was to be, and set_raw_breakpoint
/* Abstract base class representing all kinds of breakpoints. */
-struct breakpoint
+struct breakpoint : public intrusive_list_node<breakpoint>
{
breakpoint (struct gdbarch *gdbarch_, enum bptype bptype,
bool temp = true, const char *cond_string = nullptr);
/* Allocate a location for this breakpoint. */
virtual struct bp_location *allocate_location ();
+ /* Return a range of this breakpoint's locations. */
+ bp_location_range locations () const;
+
+ /* Add LOC to the location list of this breakpoint, sorted by address
+ (using LOC.ADDRESS).
+
+ LOC must have this breakpoint as its owner. LOC must not already be linked
+ in a location list. */
+ void add_location (bp_location &loc);
+
+ /* Remove LOC from this breakpoint's location list. The name is a bit funny
+ because remove_location is already taken, and means something else.
+
+ LOC must be have this breakpoints as its owner. LOC must be linked in this
+ breakpoint's location list. */
+ void unadd_location (bp_location &loc);
+
+ /* Clear the location list of this breakpoint. */
+ void clear_locations ()
+ { m_locations.clear (); }
+
+ /* Split all locations of this breakpoint that are bound to PSPACE out of its
+ location list to a separate list and return that list. If
+ PSPACE is nullptr, hoist out all locations. */
+ bp_location_list steal_locations (program_space *pspace);
+
+ /* Return true if this breakpoint has a least one location. */
+ bool has_locations () const
+ { return !m_locations.empty (); }
+
+ /* Return true if this breakpoint has a single location. */
+ bool has_single_location () const
+ {
+ if (!this->has_locations ())
+ return false;
+
+ return std::next (m_locations.begin ()) == m_locations.end ();
+ }
+
+ /* Return true if this breakpoint has multiple locations. */
+ bool has_multiple_locations () const
+ {
+ if (!this->has_locations ())
+ return false;
+
+ return std::next (m_locations.begin ()) != m_locations.end ();
+ }
+
+ /* Return a reference to the first location of this breakpoint. */
+ bp_location &first_loc ()
+ {
+ gdb_assert (this->has_locations ());
+ return m_locations.front ();
+ }
+
+ /* Return a reference to the first location of this breakpoint. */
+ const bp_location &first_loc () const
+ {
+ gdb_assert (this->has_locations ());
+ return m_locations.front ();
+ }
+
+ /* Return a reference to the last location of this breakpoint. */
+ const bp_location &last_loc () const
+ {
+ gdb_assert (this->has_locations ());
+ return m_locations.back ();
+ }
+
/* Reevaluate a breakpoint. This is necessary after symbols change
(e.g., an executable or DSO was loaded, or the inferior just
started). */
/* Display information about this breakpoint, for "info
breakpoints". Returns false if this method should use the
default behavior. */
- virtual bool print_one (bp_location **) const
+ virtual bool print_one (const bp_location **) const
{
return false;
}
/* Nothing to do. */
}
- /* Return a range of this breakpoint's locations. */
- bp_location_range locations () const;
-
- breakpoint *next = NULL;
/* Type of breakpoint. */
bptype type = bp_none;
/* Zero means disabled; remember the info but don't break here. */
/* Number assigned to distinguish breakpoints. */
int number = 0;
- /* Location(s) associated with this high-level breakpoint. */
- bp_location *loc = NULL;
-
/* True means a silent breakpoint (don't print frame info if we stop
here). */
bool silent = false;
care. */
int thread = -1;
- /* Ada task number for task-specific breakpoint, or 0 if don't
+ /* Inferior number for inferior-specific breakpoint, or -1 if this
+ breakpoint is for all inferiors. */
+ int inferior = -1;
+
+ /* Ada task number for task-specific breakpoint, or -1 if don't
care. */
- int task = 0;
+ int task = -1;
/* Count of the number of times this breakpoint was taken, dumped
with the info, but not used for anything else. Useful for seeing
thread 1", which needs outputting before any breakpoint-type
specific extra command necessary for B's recreation. */
void print_recreate_thread (struct ui_file *fp) const;
+
+ /* Location(s) associated with this high-level breakpoint. */
+ bp_location_list m_locations;
};
/* Abstract base class representing code breakpoints. User "break"
gdb::unique_xmalloc_ptr<char> cond_string,
gdb::unique_xmalloc_ptr<char> extra_string,
enum bpdisp disposition,
- int thread, int task, int ignore_count,
+ int thread, int task, int inferior, int ignore_count,
int from_tty,
int enabled, unsigned flags,
int display_canonical);
(location_spec *locspec,
struct program_space *search_pspace,
int *found);
+
+ /* Helper for breakpoint and tracepoint breakpoint->mention
+ callbacks. */
+ void say_where () const;
};
/* An instance of this type is used to represent a watchpoint,
target and breakpoint_created observers of its existence. If
INTERNAL is non-zero, the breakpoint number will be allocated from
the internal breakpoint count. If UPDATE_GLL is non-zero,
- update_global_location_list will be called. */
+ update_global_location_list will be called.
-extern void install_breakpoint (int internal, std::unique_ptr<breakpoint> &&b,
- int update_gll);
+ Takes ownership of B, and returns a non-owning reference to it. */
+
+extern breakpoint *install_breakpoint
+ (int internal, std::unique_ptr<breakpoint> &&b, int update_gll);
/* Returns the breakpoint ops appropriate for use with with LOCSPEC
and according to IS_TRACEPOINT. Use this to ensure, for example,
extern int create_breakpoint (struct gdbarch *gdbarch,
struct location_spec *locspec,
const char *cond_string, int thread,
+ int inferior,
const char *extra_string,
bool force_condition,
int parse_extra,
extern void breakpoint_set_silent (struct breakpoint *b, int silent);
+/* Set the thread for this breakpoint. If THREAD is -1, make the
+ breakpoint work for any thread. Passing a value other than -1 for
+ THREAD should only be done if b->task is 0; it is not valid to try and
+ set both a thread and task restriction on a breakpoint. */
+
extern void breakpoint_set_thread (struct breakpoint *b, int thread);
+/* Set the inferior for breakpoint B to INFERIOR. If INFERIOR is -1, make
+ the breakpoint work for any inferior. */
+
+extern void breakpoint_set_inferior (struct breakpoint *b, int inferior);
+
+/* Set the task for this breakpoint. If TASK is -1, make the breakpoint
+ work for any task. Passing a value other than -1 for TASK should only
+ be done if b->thread is -1; it is not valid to try and set both a thread
+ and task restriction on a breakpoint. */
+
extern void breakpoint_set_task (struct breakpoint *b, int task);
/* Clear the "inserted" flag in all breakpoints. */
/* Breakpoint linked list iterator. */
-using breakpoint_iterator = next_iterator<breakpoint>;
+using breakpoint_list = intrusive_list<breakpoint>;
+
+using breakpoint_iterator = breakpoint_list::iterator;
/* Breakpoint linked list range. */
struct tracepoint_filter
{
- bool operator() (breakpoint *b)
- { return is_tracepoint (b); }
+ bool operator() (breakpoint &b)
+ { return is_tracepoint (&b); }
};
/* Breakpoint linked list iterator, filtering to only keep tracepoints. */
extern void enable_disable_bp_location (bp_location *loc, bool enable);
+
+/* Notify interpreters and observers that breakpoint B was modified. */
+
+extern void notify_breakpoint_modified (breakpoint *b);
+
#endif /* !defined (BREAKPOINT_H) */