static void map_breakpoint_numbers (const char *,
gdb::function_view<void (breakpoint *)>);
-static void breakpoint_re_set_default (struct breakpoint *);
+static void breakpoint_re_set_default (code_breakpoint *);
static void
- create_sals_from_location_default (struct event_location *location,
- struct linespec_result *canonical,
- enum bptype type_wanted);
-
-static void create_breakpoints_sal_default (struct gdbarch *,
- struct linespec_result *,
- gdb::unique_xmalloc_ptr<char>,
- gdb::unique_xmalloc_ptr<char>,
- enum bptype,
- enum bpdisp, int, int,
- int,
- const struct breakpoint_ops *,
- int, int, int, unsigned);
-
-static std::vector<symtab_and_line> decode_location_default
- (struct breakpoint *b, struct event_location *location,
+ create_sals_from_location_spec_default (location_spec *locspec,
+ linespec_result *canonical);
+
+static void create_breakpoints_sal (struct gdbarch *,
+ struct linespec_result *,
+ gdb::unique_xmalloc_ptr<char>,
+ gdb::unique_xmalloc_ptr<char>,
+ enum bptype,
+ enum bpdisp, int, int,
+ int,
+ int, int, int, unsigned);
+
+static std::vector<symtab_and_line> decode_location_spec_default
+ (struct breakpoint *b, struct location_spec *locspec,
struct program_space *search_pspace);
static int can_use_hardware_watchpoint
(const std::vector<value_ref_ptr> &vals);
-static void mention (struct breakpoint *);
+static void mention (const breakpoint *);
-static struct breakpoint *set_raw_breakpoint_without_location (struct gdbarch *,
- enum bptype,
- const struct breakpoint_ops *);
-static struct bp_location *add_location_to_breakpoint (struct breakpoint *,
- const struct symtab_and_line *);
+static breakpoint *add_to_breakpoint_chain (std::unique_ptr<breakpoint> &&b);
-/* This function is used in gdbtk sources and thus can not be made
- static. */
-static struct breakpoint *set_raw_breakpoint (struct gdbarch *gdbarch,
- struct symtab_and_line,
- enum bptype,
- const struct breakpoint_ops *);
+static breakpoint *add_to_breakpoint_chain (std::unique_ptr<breakpoint> &&b);
static struct breakpoint *
momentary_breakpoint_from_master (struct breakpoint *orig,
enum bptype type,
- const struct breakpoint_ops *ops,
- int loc_enabled);
+ int loc_enabled, int thread);
static void breakpoint_adjustment_warning (CORE_ADDR, CORE_ADDR, int, int);
CORE_ADDR bpaddr,
enum bptype bptype);
-static void describe_other_breakpoints (struct gdbarch *,
- struct program_space *, CORE_ADDR,
- struct obj_section *, int);
-
static int watchpoint_locations_match (struct bp_location *loc1,
struct bp_location *loc2);
static void decref_bp_location (struct bp_location **loc);
-static struct bp_location *allocate_bp_location (struct breakpoint *bpt);
+static std::vector<symtab_and_line> bkpt_probe_decode_location_spec
+ (struct breakpoint *b,
+ location_spec *locspec,
+ struct program_space *search_pspace);
+
+static bool bl_address_is_meaningful (bp_location *loc);
/* update_global_location_list's modes of operation wrt to whether to
insert locations now. */
static int strace_marker_p (struct breakpoint *b);
-/* The breakpoint_ops structure to be inherited by all breakpoint_ops
- that are implemented on top of software or hardware breakpoints
- (user breakpoints, internal and momentary breakpoints, etc.). */
-static struct breakpoint_ops bkpt_base_breakpoint_ops;
+static void bkpt_probe_create_sals_from_location_spec
+ (location_spec *locspec,
+ struct linespec_result *canonical);
+static void tracepoint_probe_create_sals_from_location_spec
+ (location_spec *locspec,
+ struct linespec_result *canonical);
-/* The breakpoint_ops structure to be used in regular user created
- breakpoints. */
-struct breakpoint_ops bkpt_breakpoint_ops;
+const struct breakpoint_ops code_breakpoint_ops =
+{
+ create_sals_from_location_spec_default,
+ create_breakpoints_sal,
+};
/* Breakpoints set on probes. */
-static struct breakpoint_ops bkpt_probe_breakpoint_ops;
+static const struct breakpoint_ops bkpt_probe_breakpoint_ops =
+{
+ bkpt_probe_create_sals_from_location_spec,
+ create_breakpoints_sal,
+};
/* Tracepoints set on probes. */
-static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
+static const struct breakpoint_ops tracepoint_probe_breakpoint_ops =
+{
+ tracepoint_probe_create_sals_from_location_spec,
+ create_breakpoints_sal,
+};
-/* Dynamic printf class type. */
-struct breakpoint_ops dprintf_breakpoint_ops;
+/* Implementation of abstract dtors. These must exist to satisfy the
+ linker. */
+
+breakpoint::~breakpoint ()
+{
+}
+
+code_breakpoint::~code_breakpoint ()
+{
+}
+
+catchpoint::~catchpoint ()
+{
+}
/* The structure to be used in regular breakpoints. */
-struct ordinary_breakpoint : public base_breakpoint
+struct ordinary_breakpoint : public code_breakpoint
{
+ using code_breakpoint::code_breakpoint;
+
+ int resources_needed (const struct bp_location *) override;
+ enum print_stop_action print_it (const bpstat *bs) const override;
+ void print_mention () const override;
+ void print_recreate (struct ui_file *fp) const override;
};
-/* Internal breakpoints. */
-struct internal_breakpoint : public base_breakpoint
+/* Internal breakpoints. These typically have a lifetime the same as
+ the program, and they end up installed on the breakpoint chain with
+ a negative breakpoint number. They're visible in "maint info
+ breakpoints", but not "info breakpoints". */
+struct internal_breakpoint : public code_breakpoint
{
+ internal_breakpoint (struct gdbarch *gdbarch,
+ enum bptype type, CORE_ADDR address)
+ : code_breakpoint (gdbarch, type)
+ {
+ symtab_and_line sal;
+ sal.pc = address;
+ sal.section = find_pc_overlay (sal.pc);
+ sal.pspace = current_program_space;
+ add_location (sal);
+
+ pspace = current_program_space;
+ disposition = disp_donttouch;
+ }
+
void re_set () override;
void check_status (struct bpstat *bs) override;
- enum print_stop_action print_it (struct bpstat *bs) override;
- void print_mention () override;
+ enum print_stop_action print_it (const bpstat *bs) const override;
+ void print_mention () const override;
};
-/* Momentary breakpoints. */
-struct momentary_breakpoint : public base_breakpoint
-{
+/* Momentary breakpoints. These typically have a lifetime of some run
+ control command only, are always thread-specific, and have 0 for
+ breakpoint number. I.e., there can be many momentary breakpoints
+ on the breakpoint chain and they all same the same number (zero).
+ They're visible in "maint info breakpoints", but not "info
+ breakpoints". */
+struct momentary_breakpoint : public code_breakpoint
+{
+ momentary_breakpoint (struct gdbarch *gdbarch_, enum bptype bptype,
+ program_space *pspace_,
+ const struct frame_id &frame_id_,
+ int thread_)
+ : code_breakpoint (gdbarch_, bptype)
+ {
+ /* If FRAME_ID is valid, it should be a real frame, not an inlined
+ or tail-called one. */
+ gdb_assert (!frame_id_artificial_p (frame_id));
+
+ /* Momentary breakpoints are always thread-specific. */
+ gdb_assert (thread_ > 0);
+
+ pspace = pspace_;
+ enable_state = bp_enabled;
+ disposition = disp_donttouch;
+ frame_id = frame_id_;
+ thread = thread_;
+ }
+
void re_set () override;
void check_status (struct bpstat *bs) override;
- enum print_stop_action print_it (struct bpstat *bs) override;
- void print_mention () override;
+ enum print_stop_action print_it (const bpstat *bs) const override;
+ void print_mention () const override;
};
/* DPrintf breakpoints. */
struct dprintf_breakpoint : public ordinary_breakpoint
{
+ using ordinary_breakpoint::ordinary_breakpoint;
+
+ void re_set () override;
+ int breakpoint_hit (const struct bp_location *bl,
+ const address_space *aspace,
+ CORE_ADDR bp_addr,
+ const target_waitstatus &ws) override;
+ void print_recreate (struct ui_file *fp) const override;
+ void after_condition_true (struct bpstat *bs) override;
+};
+
+/* Ranged breakpoints. */
+struct ranged_breakpoint : public ordinary_breakpoint
+{
+ explicit ranged_breakpoint (struct gdbarch *gdbarch,
+ const symtab_and_line &sal_start,
+ int length,
+ location_spec_up start_locspec,
+ location_spec_up end_locspec)
+ : ordinary_breakpoint (gdbarch, bp_hardware_breakpoint)
+ {
+ bp_location *bl = add_location (sal_start);
+ bl->length = length;
+
+ disposition = disp_donttouch;
+
+ locspec = std::move (start_locspec);
+ locspec_range_end = std::move (end_locspec);
+ }
+
+ int breakpoint_hit (const struct bp_location *bl,
+ const address_space *aspace,
+ CORE_ADDR bp_addr,
+ const target_waitstatus &ws) override;
+ int resources_needed (const struct bp_location *) override;
+ enum print_stop_action print_it (const bpstat *bs) const override;
+ bool print_one (bp_location **) const override;
+ void print_one_detail (struct ui_out *) const override;
+ void print_mention () const override;
+ void print_recreate (struct ui_file *fp) const override;
+};
+
+/* Static tracepoints with marker (`-m'). */
+struct static_marker_tracepoint : public tracepoint
+{
+ using tracepoint::tracepoint;
+
+ std::vector<symtab_and_line> decode_location_spec
+ (struct location_spec *locspec,
+ struct program_space *search_pspace) override;
};
/* The style in which to perform a dynamic printf. This is a user
struct longjmp_breakpoint : public momentary_breakpoint
{
+ using momentary_breakpoint::momentary_breakpoint;
+
~longjmp_breakpoint () override;
};
{
return (type == bp_tracepoint
|| type == bp_fast_tracepoint
- || type == bp_static_tracepoint);
+ || type == bp_static_tracepoint
+ || type == bp_static_marker_tracepoint);
}
/* See breakpoint.h. */
/* Factory function to create an appropriate instance of breakpoint given
TYPE. */
-static std::unique_ptr<breakpoint>
-new_breakpoint_from_type (bptype type)
+template<typename... Arg>
+static std::unique_ptr<code_breakpoint>
+new_breakpoint_from_type (struct gdbarch *gdbarch, bptype type,
+ Arg&&... args)
{
- breakpoint *b;
+ code_breakpoint *b;
switch (type)
{
case bp_breakpoint:
case bp_hardware_breakpoint:
- b = new ordinary_breakpoint ();
+ b = new ordinary_breakpoint (gdbarch, type,
+ std::forward<Arg> (args)...);
break;
case bp_fast_tracepoint:
case bp_static_tracepoint:
case bp_tracepoint:
- b = new tracepoint ();
- break;
-
- case bp_dprintf:
- b = new dprintf_breakpoint ();
- break;
-
- case bp_overlay_event:
- case bp_longjmp_master:
- case bp_std_terminate_master:
- case bp_exception_master:
- case bp_thread_event:
- case bp_jit_event:
- case bp_shlib_event:
- b = new internal_breakpoint ();
+ b = new tracepoint (gdbarch, type,
+ std::forward<Arg> (args)...);
break;
- case bp_longjmp:
- case bp_exception:
- b = new longjmp_breakpoint ();
+ case bp_static_marker_tracepoint:
+ b = new static_marker_tracepoint (gdbarch, type,
+ std::forward<Arg> (args)...);
break;
- case bp_watchpoint_scope:
- case bp_finish:
- case bp_gnu_ifunc_resolver_return:
- case bp_step_resume:
- case bp_hp_step_resume:
- case bp_longjmp_resume:
- case bp_longjmp_call_dummy:
- case bp_exception_resume:
- case bp_call_dummy:
- case bp_until:
- case bp_std_terminate:
- b = new momentary_breakpoint ();
+ case bp_dprintf:
+ b = new dprintf_breakpoint (gdbarch, type,
+ std::forward<Arg> (args)...);
break;
default:
gdb_assert_not_reached ("invalid type");
}
- return std::unique_ptr<breakpoint> (b);
+ return std::unique_ptr<code_breakpoint> (b);
}
/* A helper function that validates that COMMANDS are valid for a
if (b->type == bp_fast_tracepoint)
error (_("The 'while-stepping' command "
"cannot be used for fast tracepoint"));
- else if (b->type == bp_static_tracepoint)
+ else if (b->type == bp_static_tracepoint
+ || b->type == bp_static_marker_tracepoint)
error (_("The 'while-stepping' command "
"cannot be used for static tracepoint"));
std::vector<breakpoint *> found;
for (breakpoint *b : all_breakpoints ())
- if (b->type == bp_static_tracepoint)
+ if (b->type == bp_static_tracepoint
+ || b->type == bp_static_marker_tracepoint)
{
for (bp_location *loc : b->locations ())
if (loc->address == addr)
return bit_val;
}
-/* Allocate a dummy location and add it to B, which must be a software
- watchpoint. This is required because even if a software watchpoint
- is not watching any memory, bpstat_stop_status requires a location
- to be able to report stops. */
+/* Allocate a dummy location and add it to B. This is required
+ because bpstat_stop_status requires a location to be able to report
+ stops. */
static void
-software_watchpoint_add_no_memory_location (struct breakpoint *b,
- struct program_space *pspace)
+add_dummy_location (struct breakpoint *b,
+ struct program_space *pspace)
{
- gdb_assert (b->type == bp_watchpoint && b->loc == NULL);
+ gdb_assert (b->loc == NULL);
- b->loc = allocate_bp_location (b);
+ b->loc = new bp_location (b, bp_loc_other);
b->loc->pspace = pspace;
- b->loc->address = -1;
- b->loc->length = -1;
-}
-
-/* Returns true if B is a software watchpoint that is not watching any
- memory (e.g., "watch $pc"). */
-
-static bool
-is_no_memory_software_watchpoint (struct breakpoint *b)
-{
- return (b->type == bp_watchpoint
- && b->loc != NULL
- && b->loc->next == NULL
- && b->loc->address == -1
- && b->loc->length == -1);
}
/* Assuming that B is a watchpoint:
the target gains execution, through breakpoint_re_set. */
if (!can_use_hw_watchpoints)
{
- if (b->ops->works_in_software_mode (b))
+ if (b->works_in_software_mode ())
b->type = bp_watchpoint;
else
error (_("Can't set read/access watchpoint when "
else if (b->type == bp_access_watchpoint)
type = hw_access;
- loc = allocate_bp_location (b);
+ loc = b->allocate_location ();
for (tmp = &(b->loc); *tmp != NULL; tmp = &((*tmp)->next))
;
*tmp = loc;
= target_can_use_hardware_watchpoint (type, i, other_type_used);
if (target_resources_ok <= 0)
{
- int sw_mode = b->ops->works_in_software_mode (b);
+ bool sw_mode = b->works_in_software_mode ();
if (target_resources_ok == 0 && !sw_mode)
error (_("Target does not support this type of "
b->type = type;
}
}
- else if (!b->ops->works_in_software_mode (b))
+ else if (!b->works_in_software_mode ())
{
if (!can_use_hw_watchpoints)
error (_("Can't set read/access watchpoint when "
else
b->type = bp_watchpoint;
- loc_type = (b->type == bp_watchpoint? bp_loc_other
+ loc_type = (b->type == bp_watchpoint? bp_loc_software_watchpoint
: bp_loc_hardware_watchpoint);
for (bp_location *bl : b->locations ())
bl->loc_type = loc_type;
bpstat_stop_status requires a location to be able to report
stops, so make sure there's at least a dummy one. */
if (b->type == bp_watchpoint && b->loc == NULL)
- software_watchpoint_add_no_memory_location (b, frame_pspace);
+ add_dummy_location (b, frame_pspace);
}
else if (!within_current_scope)
{
{
int val;
- val = bl->owner->ops->insert_location (bl);
+ val = bl->owner->insert_location (bl);
if (val)
bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
}
{
int val;
- val = bl->owner->ops->insert_location (bl);
+ val = bl->owner->insert_location (bl);
if (val)
bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
}
{
int val;
- gdb_assert (bl->owner->ops != NULL
- && bl->owner->ops->insert_location != NULL);
-
- val = bl->owner->ops->insert_location (bl);
+ val = bl->owner->insert_location (bl);
/* If trying to set a read-watchpoint, and it turns out it's not
supported, try emulating one with an access watchpoint. */
if (val == 1)
{
bl->watchpoint_type = hw_access;
- val = bl->owner->ops->insert_location (bl);
+ val = bl->owner->insert_location (bl);
if (val)
/* Back to the original value. */
{
int val;
- gdb_assert (bl->owner->ops != NULL
- && bl->owner->ops->insert_location != NULL);
-
- val = bl->owner->ops->insert_location (bl);
+ val = bl->owner->insert_location (bl);
if (val)
{
bl->owner->enable_state = bp_disabled;
static struct breakpoint *
create_internal_breakpoint (struct gdbarch *gdbarch,
- CORE_ADDR address, enum bptype type,
- const struct breakpoint_ops *ops)
+ CORE_ADDR address, enum bptype type)
{
- symtab_and_line sal;
- sal.pc = address;
- sal.section = find_pc_overlay (sal.pc);
- sal.pspace = current_program_space;
+ std::unique_ptr<internal_breakpoint> b
+ (new internal_breakpoint (gdbarch, type, address));
- breakpoint *b = set_raw_breakpoint (gdbarch, sal, type, ops);
b->number = internal_breakpoint_number--;
- b->disposition = disp_donttouch;
- return b;
+ return add_to_breakpoint_chain (std::move (b));
}
static const char *const longjmp_names[] =
struct breakpoint *b;
struct breakpoint_objfile_data *bp_objfile_data;
CORE_ADDR addr;
- struct explicit_location explicit_loc;
bp_objfile_data = get_breakpoint_objfile_data (objfile);
addr = bp_objfile_data->overlay_msym.value_address ();
b = create_internal_breakpoint (objfile->arch (), addr,
- bp_overlay_event,
- &vtable_breakpoint_ops);
- initialize_explicit_location (&explicit_loc);
- explicit_loc.function_name = ASTRDUP (func_name);
- b->location = new_explicit_location (&explicit_loc);
+ bp_overlay_event);
+ b->locspec = new_explicit_location_spec_function (func_name);
if (overlay_debugging == ovly_auto)
{
b = create_internal_breakpoint (gdbarch,
p->get_relocated_address (objfile),
- bp_longjmp_master,
- &vtable_breakpoint_ops);
- b->location = new_probe_location ("-probe-stap libc:longjmp");
+ bp_longjmp_master);
+ b->locspec = new_probe_location_spec ("-probe-stap libc:longjmp");
b->enable_state = bp_disabled;
}
struct breakpoint *b;
const char *func_name;
CORE_ADDR addr;
- struct explicit_location explicit_loc;
if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym))
continue;
}
addr = bp_objfile_data->longjmp_msym[i].value_address ();
- b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master,
- &vtable_breakpoint_ops);
- initialize_explicit_location (&explicit_loc);
- explicit_loc.function_name = ASTRDUP (func_name);
- b->location = new_explicit_location (&explicit_loc);
+ b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master);
+ b->locspec = new_explicit_location_spec_function (func_name);
b->enable_state = bp_disabled;
installed_bp++;
}
{
struct breakpoint *b;
struct breakpoint_objfile_data *bp_objfile_data;
- struct explicit_location explicit_loc;
bp_objfile_data = get_breakpoint_objfile_data (objfile);
addr = bp_objfile_data->terminate_msym.value_address ();
b = create_internal_breakpoint (objfile->arch (), addr,
- bp_std_terminate_master,
- &vtable_breakpoint_ops);
- initialize_explicit_location (&explicit_loc);
- explicit_loc.function_name = ASTRDUP (func_name);
- b->location = new_explicit_location (&explicit_loc);
+ bp_std_terminate_master);
+ b->locspec = new_explicit_location_spec_function (func_name);
b->enable_state = bp_disabled;
}
}
{
b = create_internal_breakpoint (gdbarch,
p->get_relocated_address (objfile),
- bp_exception_master,
- &vtable_breakpoint_ops);
- b->location = new_probe_location ("-probe-stap libgcc:unwind");
+ bp_exception_master);
+ b->locspec = new_probe_location_spec ("-probe-stap libgcc:unwind");
b->enable_state = bp_disabled;
}
struct gdbarch *gdbarch;
struct breakpoint_objfile_data *bp_objfile_data;
CORE_ADDR addr;
- struct explicit_location explicit_loc;
bp_objfile_data = get_breakpoint_objfile_data (objfile);
addr = bp_objfile_data->exception_msym.value_address ();
addr = gdbarch_convert_from_func_ptr_addr
(gdbarch, addr, current_inferior ()->top_target ());
- b = create_internal_breakpoint (gdbarch, addr, bp_exception_master,
- &vtable_breakpoint_ops);
- initialize_explicit_location (&explicit_loc);
- explicit_loc.function_name = ASTRDUP (func_name);
- b->location = new_explicit_location (&explicit_loc);
+ b = create_internal_breakpoint (gdbarch, addr, bp_exception_master);
+ b->locspec = new_explicit_location_spec_function (func_name);
b->enable_state = bp_disabled;
return true;
/* Does B have a location spec? */
static int
-breakpoint_event_location_empty_p (const struct breakpoint *b)
+breakpoint_location_spec_empty_p (const struct breakpoint *b)
{
- return b->location != NULL && event_location_empty_p (b->location.get ());
+ return (b->locspec != nullptr && b->locspec->empty_p ());
}
void
/* Without a symbolic address, we have little hope of the
pre-exec() address meaning the same thing in the post-exec()
a.out. */
- if (breakpoint_event_location_empty_p (b))
+ if (breakpoint_location_spec_empty_p (b))
{
delete_breakpoint (b);
continue;
/* This function must physically remove breakpoints locations
from the specified ptid, without modifying the breakpoint
- package's state. Locations of type bp_loc_other are only
- maintained at GDB side. So, there is no need to remove
- these bp_loc_other locations. Moreover, removing these
+ package's state. Locations of type bp_loc_other and
+ bp_loc_software_watchpoint are only maintained at GDB side,
+ so there is no need to remove them. Moreover, removing these
would modify the breakpoint package's state. */
- if (bl->loc_type == bp_loc_other)
+ if (bl->loc_type == bp_loc_other
+ || bl->loc_type == bp_loc_software_watchpoint)
continue;
if (bl->inserted)
&& !memory_validate_breakpoint (bl->gdbarch, &bl->target_info))
val = 0;
else
- val = bl->owner->ops->remove_location (bl, reason);
+ val = bl->owner->remove_location (bl, reason);
}
else
{
wrong code with the saved shadow contents. */
if (bl->loc_type == bp_loc_hardware_breakpoint
|| section_is_mapped (bl->section))
- val = bl->owner->ops->remove_location (bl, reason);
+ val = bl->owner->remove_location (bl, reason);
else
val = 0;
}
}
else if (bl->loc_type == bp_loc_hardware_watchpoint)
{
- gdb_assert (bl->owner->ops != NULL
- && bl->owner->ops->remove_location != NULL);
-
bl->inserted = (reason == DETACH_BREAKPOINT);
- bl->owner->ops->remove_location (bl, reason);
+ bl->owner->remove_location (bl, reason);
/* Failure to remove any of the hardware watchpoints comes here. */
if (reason == REMOVE_BREAKPOINT && bl->inserted)
&& breakpoint_enabled (bl->owner)
&& !bl->duplicate)
{
- gdb_assert (bl->owner->ops != NULL
- && bl->owner->ops->remove_location != NULL);
-
- val = bl->owner->ops->remove_location (bl, reason);
+ val = bl->owner->remove_location (bl, reason);
if (val)
return val;
}
else
{
- if (bsp->breakpoint_at->ops->explains_signal (bsp->breakpoint_at,
- sig))
+ if (bsp->breakpoint_at->explains_signal (sig))
return true;
}
}
return PRINT_UNKNOWN;
/* Normal case. Call the breakpoint's print_it method. */
- return b->ops->print_it (bs);
+ return b->print_it (bs);
}
break;
watch after that (since the garbage may or may not equal
the first value assigned). */
/* We print all the stop information in
- breakpoint_ops->print_it, but in this case, by the time we
- call breakpoint_ops->print_it this bp will be deleted
+ breakpointprint_it, but in this case, by the time we
+ call breakpoint->print_it this bp will be deleted
already. So we have no choice but print the information
here. */
/* BL is from an existing breakpoint. */
gdb_assert (b != NULL);
- return b->ops->breakpoint_hit (bl, aspace, bp_addr, ws);
+ return b->breakpoint_hit (bl, aspace, bp_addr, ws);
}
/* Determine if the watched values have actually changed, and we
continue;
b = bs->breakpoint_at;
- b->ops->check_status (bs);
+ b->check_status (bs);
if (bs->stop)
{
bpstat_check_breakpoint_conditions (bs, thread);
? bs->commands.get () : NULL))
bs->print = 0;
- b->ops->after_condition_true (bs);
+ b->after_condition_true (bs);
}
}
{
/* Some catchpoints are implemented with breakpoints.
For those, we need to step over the breakpoint. */
- if (bs->bp_location_at->loc_type != bp_loc_other)
+ if (bs->bp_location_at->loc_type == bp_loc_software_breakpoint
+ || bs->bp_location_at->loc_type == bp_loc_hardware_breakpoint)
this_action = BPSTAT_WHAT_SINGLE;
}
break;
case bp_tracepoint:
case bp_fast_tracepoint:
case bp_static_tracepoint:
+ case bp_static_marker_tracepoint:
/* Tracepoint hits should not be reported back to GDB, and
if one got through somehow, it should have been filtered
out already. */
handle_jit_event (bs->bp_location_at->address);
break;
case bp_gnu_ifunc_resolver:
- gnu_ifunc_resolver_stop (b);
+ gnu_ifunc_resolver_stop ((code_breakpoint *) b);
break;
case bp_gnu_ifunc_resolver_return:
- gnu_ifunc_resolver_return_stop (b);
+ gnu_ifunc_resolver_return_stop ((code_breakpoint *) b);
break;
}
}
*/
static const char *
-bp_condition_evaluator (struct breakpoint *b)
+bp_condition_evaluator (const breakpoint *b)
{
char host_evals = 0;
char target_evals = 0;
/* Print the LOC location out of the list of B->LOC locations. */
static void
-print_breakpoint_location (struct breakpoint *b,
+print_breakpoint_location (const breakpoint *b,
struct bp_location *loc)
{
struct ui_out *uiout = current_uiout;
set_current_program_space (loc->pspace);
if (b->display_canonical)
- uiout->field_string ("what", event_location_to_string (b->location.get ()));
+ uiout->field_string ("what",
+ location_spec_to_string (b->locspec.get ()));
else if (loc && loc->symtab)
{
const struct symbol *sym = loc->symbol;
else
{
uiout->field_string ("pending",
- event_location_to_string (b->location.get ()));
+ location_spec_to_string (b->locspec.get ()));
/* If extra_string is available, it could be holding a condition
or dprintf arguments. In either case, make sure it is printed,
too, but only for non-MI streams. */
{bp_tracepoint, "tracepoint"},
{bp_fast_tracepoint, "fast tracepoint"},
{bp_static_tracepoint, "static tracepoint"},
+ {bp_static_marker_tracepoint, "static marker tracepoint"},
{bp_dprintf, "dprintf"},
{bp_jit_event, "jit events"},
{bp_gnu_ifunc_resolver, "STT_GNU_IFUNC resolver"},
/* 4 */
annotate_field (3);
- /* For locations that are disabled because of an invalid condition,
- display "N*" on CLI, where "*" refers to a footnote below the
- table. For MI, simply display a "N" without a footnote. */
- const char *N = (uiout->is_mi_like_p ()) ? "N" : "N*";
if (part_of_multiple)
- uiout->field_string ("enabled", (loc->disabled_by_cond ? N
- : (loc->enabled ? "y" : "n")));
+ {
+ /* For locations that are disabled because of an invalid
+ condition, display "N*" on the CLI, where "*" refers to a
+ footnote below the table. For MI, simply display a "N"
+ without a footnote. On the CLI, for enabled locations whose
+ breakpoint is disabled, display "y-". */
+ auto get_enable_state = [uiout, loc] () -> const char *
+ {
+ if (uiout->is_mi_like_p ())
+ {
+ if (loc->disabled_by_cond)
+ return "N";
+ else if (!loc->enabled)
+ return "n";
+ else
+ return "y";
+ }
+ else
+ {
+ if (loc->disabled_by_cond)
+ return "N*";
+ else if (!loc->enabled)
+ return "n";
+ else if (!breakpoint_enabled (loc->owner))
+ return "y-";
+ else
+ return "y";
+ }
+ };
+ uiout->field_string ("enabled", get_enable_state ());
+ }
else
uiout->field_fmt ("enabled", "%c", bpenables[(int) b->enable_state]);
/* 5 and 6 */
bool result = false;
- if (!raw_loc && b->ops != NULL && b->ops->print_one (b, last_loc))
+ if (!raw_loc && b->print_one (last_loc))
result = true;
else
{
uiout->text ("\n");
if (!part_of_multiple)
- b->ops->print_one_detail (b, uiout);
+ b->print_one_detail (uiout);
if (part_of_multiple && frame_id_p (b->frame_id))
{
uiout->field_string ("original-location", w->exp_string.get ());
}
- else if (b->location != NULL
- && event_location_to_string (b->location.get ()) != NULL)
- uiout->field_string ("original-location",
- event_location_to_string (b->location.get ()));
+ else if (b->locspec != nullptr)
+ {
+ const char *str = location_spec_to_string (b->locspec.get ());
+ if (str != nullptr)
+ uiout->field_string ("original-location", str);
+ }
}
return result;
{
int print_address_bits = 0;
- /* Software watchpoints that aren't watching memory don't have an
- address to print. */
- if (is_no_memory_software_watchpoint (b))
- return 0;
-
for (bp_location *loc : b->locations ())
{
- int addr_bit;
+ if (!bl_address_is_meaningful (loc))
+ continue;
- addr_bit = gdbarch_addr_bit (loc->gdbarch);
+ int addr_bit = gdbarch_addr_bit (loc->gdbarch);
if (addr_bit > print_address_bits)
print_address_bits = addr_bit;
}
return 0;
}
-/* Print a message describing any user-breakpoints set at PC. This
- concerns with logical breakpoints, so we match program spaces, not
- address spaces. */
+/* See breakpoint.h. */
-static void
+void
describe_other_breakpoints (struct gdbarch *gdbarch,
struct program_space *pspace, CORE_ADDR pc,
struct obj_section *section, int thread)
case bp_access_watchpoint:
return bp_loc_hardware_watchpoint;
case bp_watchpoint:
+ return bp_loc_software_watchpoint;
case bp_catchpoint:
case bp_tracepoint:
case bp_fast_tracepoint:
case bp_static_tracepoint:
+ case bp_static_marker_tracepoint:
return bp_loc_other;
default:
internal_error (__FILE__, __LINE__, _("unknown breakpoint type"));
{
}
-/* Allocate a struct bp_location. */
-
-static struct bp_location *
-allocate_bp_location (struct breakpoint *bpt)
-{
- return bpt->ops->allocate_location (bpt);
-}
-
/* Decrement reference count. If the reference count reaches 0,
destroy the bp_location. Sets *BLP to NULL. */
return result;
}
-/* Initializes breakpoint B with type BPTYPE and no locations yet. */
-
-static void
-init_raw_breakpoint_without_location (struct breakpoint *b,
- struct gdbarch *gdbarch,
- enum bptype bptype,
- const struct breakpoint_ops *ops)
-{
- gdb_assert (ops != NULL);
-
- b->ops = ops;
- b->type = bptype;
- b->gdbarch = gdbarch;
- b->language = current_language->la_language;
- b->input_radix = input_radix;
- b->related_breakpoint = b;
-}
-
-/* Helper to set_raw_breakpoint below. Creates a breakpoint
- that has type BPTYPE and has no locations as yet. */
-
-static struct breakpoint *
-set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
- enum bptype bptype,
- const struct breakpoint_ops *ops)
-{
- std::unique_ptr<breakpoint> b = new_breakpoint_from_type (bptype);
-
- init_raw_breakpoint_without_location (b.get (), gdbarch, bptype, ops);
- return add_to_breakpoint_chain (std::move (b));
-}
-
/* Initialize loc->function_name. */
static void
return NULL;
}
-/* Low level routine for partially initializing a breakpoint of type
- BPTYPE. The newly created breakpoint's address, section, source
- file name, and line number are provided by SAL.
-
- It is expected that the caller will complete the initialization of
- the newly created breakpoint struct as well as output any status
- information regarding the creation of a new breakpoint. */
-
-static void
-init_raw_breakpoint (struct breakpoint *b, struct gdbarch *gdbarch,
- struct symtab_and_line sal, enum bptype bptype,
- const struct breakpoint_ops *ops)
-{
- init_raw_breakpoint_without_location (b, gdbarch, bptype, ops);
-
- add_location_to_breakpoint (b, &sal);
-
- if (bptype != bp_catchpoint)
- gdb_assert (sal.pspace != NULL);
-
- /* Store the program space that was used to set the breakpoint,
- except for ordinary breakpoints, which are independent of the
- program space. */
- if (bptype != bp_breakpoint && bptype != bp_hardware_breakpoint)
- b->pspace = sal.pspace;
-}
-
-/* set_raw_breakpoint is a low level routine for allocating and
- partially initializing a breakpoint of type BPTYPE. The newly
- created breakpoint's address, section, source file name, and line
- number are provided by SAL. The newly created and partially
- initialized breakpoint is added to the breakpoint chain and
- is also returned as the value of this function.
-
- It is expected that the caller will complete the initialization of
- the newly created breakpoint struct as well as output any status
- information regarding the creation of a new breakpoint. In
- particular, set_raw_breakpoint does NOT set the breakpoint
- number! Care should be taken to not allow an error to occur
- prior to completing the initialization of the breakpoint. If this
- should happen, a bogus breakpoint will be left on the chain. */
-
-static struct breakpoint *
-set_raw_breakpoint (struct gdbarch *gdbarch,
- struct symtab_and_line sal, enum bptype bptype,
- const struct breakpoint_ops *ops)
-{
- std::unique_ptr<breakpoint> b = new_breakpoint_from_type (bptype);
-
- init_raw_breakpoint (b.get (), gdbarch, sal, bptype, ops);
- return add_to_breakpoint_chain (std::move (b));
-}
-
/* Call this routine when stepping and nexting to enable a breakpoint
if we do a longjmp() or 'throw' in TP. FRAME is the frame which
initiated the operation. */
|| b->type == bp_exception_master))
{
enum bptype type = b->type == bp_longjmp_master ? bp_longjmp : bp_exception;
- struct breakpoint *clone;
-
/* longjmp_breakpoint_ops ensures INITIATING_FRAME is cleared again
after their removal. */
- clone = momentary_breakpoint_from_master (b, type,
- &vtable_breakpoint_ops, 1);
- clone->thread = thread;
+ momentary_breakpoint_from_master (b, type, 1, thread);
}
tp->initiating_frame = frame;
for (breakpoint *b : all_breakpoints ())
if (b->pspace == current_program_space && b->type == bp_longjmp_master)
{
- struct breakpoint *new_b;
-
- new_b = momentary_breakpoint_from_master (b, bp_longjmp_call_dummy,
- &vtable_breakpoint_ops,
- 1);
- new_b->thread = inferior_thread ()->global_num;
+ int thread = inferior_thread ()->global_num;
+ breakpoint *new_b
+ = momentary_breakpoint_from_master (b, bp_longjmp_call_dummy,
+ 1, thread);
/* Link NEW_B into the chain of RETVAL breakpoints. */
if (b->pspace == current_program_space
&& b->type == bp_std_terminate_master)
{
- momentary_breakpoint_from_master (b, bp_std_terminate,
- &vtable_breakpoint_ops, 1);
+ momentary_breakpoint_from_master (b, bp_std_terminate, 1,
+ inferior_thread ()->global_num);
}
}
{
struct breakpoint *b;
- b = create_internal_breakpoint (gdbarch, address, bp_thread_event,
- &vtable_breakpoint_ops);
+ b = create_internal_breakpoint (gdbarch, address, bp_thread_event);
b->enable_state = bp_enabled;
- /* location has to be used or breakpoint_re_set will delete me. */
- b->location = new_address_location (b->loc->address, NULL, 0);
+ /* locspec has to be used or breakpoint_re_set will delete me. */
+ b->locspec = new_address_location_spec (b->loc->address, NULL, 0);
update_global_location_list_nothrow (UGLL_MAY_INSERT);
struct breakpoint *
create_jit_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
{
- return create_internal_breakpoint (gdbarch, address, bp_jit_event,
- &vtable_breakpoint_ops);
+ return create_internal_breakpoint (gdbarch, address, bp_jit_event);
}
/* Remove JIT code registration and unregistration breakpoint(s). */
{
struct breakpoint *b;
- b = create_internal_breakpoint (gdbarch, address, bp_shlib_event,
- &vtable_breakpoint_ops);
+ b = create_internal_breakpoint (gdbarch, address, bp_shlib_event);
update_global_location_list_nothrow (insert_mode);
return b;
}
/* See breakpoint.h. */
-void
-init_catchpoint (struct breakpoint *b,
- struct gdbarch *gdbarch, bool temp,
- const char *cond_string,
- const struct breakpoint_ops *ops)
+breakpoint::breakpoint (struct gdbarch *gdbarch_, enum bptype bptype,
+ bool temp, const char *cond_string_)
+ : type (bptype),
+ disposition (temp ? disp_del : disp_donttouch),
+ gdbarch (gdbarch_),
+ language (current_language->la_language),
+ input_radix (::input_radix),
+ cond_string (cond_string_ != nullptr
+ ? make_unique_xstrdup (cond_string_)
+ : nullptr),
+ related_breakpoint (this)
{
- symtab_and_line sal;
- sal.pspace = current_program_space;
+}
- init_raw_breakpoint (b, gdbarch, sal, bp_catchpoint, ops);
+/* See breakpoint.h. */
- if (cond_string == nullptr)
- b->cond_string.reset ();
- else
- b->cond_string = make_unique_xstrdup (cond_string);
- b->disposition = temp ? disp_del : disp_donttouch;
+catchpoint::catchpoint (struct gdbarch *gdbarch, bool temp,
+ const char *cond_string)
+ : breakpoint (gdbarch, bp_catchpoint, temp, cond_string)
+{
+ add_dummy_location (this, current_program_space);
+
+ pspace = current_program_space;
}
void
{
/* Special types of hardware breakpoints may use more than
one register. */
- i += b->ops->resources_needed (bl);
+ i += b->resources_needed (bl);
}
return i;
{
/* Special types of hardware watchpoints may use more than
one register. */
- i += b->ops->resources_needed (bl);
+ i += b->resources_needed (bl);
}
return i;
breakpoint_re_set ();
}
-/* Create a new single-step breakpoint for thread THREAD, with no
- locations. */
+/* Allocate a new momentary breakpoint. */
-static struct breakpoint *
-new_single_step_breakpoint (int thread, struct gdbarch *gdbarch)
+template<typename... Arg>
+static momentary_breakpoint *
+new_momentary_breakpoint (struct gdbarch *gdbarch, enum bptype type,
+ Arg&&... args)
{
- std::unique_ptr<breakpoint> b (new momentary_breakpoint ());
-
- init_raw_breakpoint_without_location (b.get (), gdbarch, bp_single_step,
- &vtable_breakpoint_ops);
-
- b->disposition = disp_donttouch;
- b->frame_id = null_frame_id;
-
- b->thread = thread;
- gdb_assert (b->thread != 0);
-
- return add_to_breakpoint_chain (std::move (b));
+ if (type == bp_longjmp || type == bp_exception)
+ return new longjmp_breakpoint (gdbarch, type,
+ std::forward<Arg> (args)...);
+ else
+ return new momentary_breakpoint (gdbarch, type,
+ std::forward<Arg> (args)...);
}
/* Set a momentary breakpoint of type TYPE at address specified by
set_momentary_breakpoint (struct gdbarch *gdbarch, struct symtab_and_line sal,
struct frame_id frame_id, enum bptype type)
{
- struct breakpoint *b;
-
/* If FRAME_ID is valid, it should be a real frame, not an inlined or
tail-called one. */
gdb_assert (!frame_id_artificial_p (frame_id));
- b = set_raw_breakpoint (gdbarch, sal, type, &vtable_breakpoint_ops);
- b->enable_state = bp_enabled;
- b->disposition = disp_donttouch;
- b->frame_id = frame_id;
+ std::unique_ptr<momentary_breakpoint> b
+ (new_momentary_breakpoint (gdbarch, type, sal.pspace, frame_id,
+ inferior_thread ()->global_num));
- b->thread = inferior_thread ()->global_num;
+ b->add_location (sal);
+
+ breakpoint_up bp (add_to_breakpoint_chain (std::move (b)));
update_global_location_list_nothrow (UGLL_MAY_INSERT);
- return breakpoint_up (b);
+ return bp;
}
/* Make a momentary breakpoint based on the master breakpoint ORIG.
static struct breakpoint *
momentary_breakpoint_from_master (struct breakpoint *orig,
enum bptype type,
- const struct breakpoint_ops *ops,
- int loc_enabled)
+ int loc_enabled,
+ int thread)
{
- struct breakpoint *copy;
-
- copy = set_raw_breakpoint_without_location (orig->gdbarch, type, ops);
- copy->loc = allocate_bp_location (copy);
+ std::unique_ptr<breakpoint> copy
+ (new_momentary_breakpoint (orig->gdbarch, type, orig->pspace,
+ orig->frame_id, thread));
+ copy->loc = copy->allocate_location ();
set_breakpoint_location_function (copy->loc);
copy->loc->gdbarch = orig->loc->gdbarch;
copy->loc->line_number = orig->loc->line_number;
copy->loc->symtab = orig->loc->symtab;
copy->loc->enabled = loc_enabled;
- copy->frame_id = orig->frame_id;
- copy->thread = orig->thread;
- copy->pspace = orig->pspace;
-
- copy->enable_state = bp_enabled;
- copy->disposition = disp_donttouch;
- copy->number = internal_breakpoint_number--;
+ breakpoint *b = add_to_breakpoint_chain (std::move (copy));
update_global_location_list_nothrow (UGLL_DONT_INSERT);
- return copy;
+ return b;
}
/* Make a deep copy of momentary breakpoint ORIG. Returns NULL if
if (orig == NULL)
return NULL;
- gdb_assert (orig->ops == &vtable_breakpoint_ops);
- return momentary_breakpoint_from_master (orig, orig->type, orig->ops, 0);
+ return momentary_breakpoint_from_master (orig, orig->type, 0,
+ orig->thread);
}
breakpoint_up
/* Tell the user we have just set a breakpoint B. */
static void
-mention (struct breakpoint *b)
+mention (const breakpoint *b)
{
- b->ops->print_mention (b);
+ b->print_mention ();
current_uiout->text ("\n");
}
\f
}
}
-static struct bp_location *
-add_location_to_breakpoint (struct breakpoint *b,
- const struct symtab_and_line *sal)
+bp_location *
+code_breakpoint::add_location (const symtab_and_line &sal)
{
- struct bp_location *loc, **tmp;
+ struct bp_location *new_loc, **tmp;
CORE_ADDR adjusted_address;
- struct gdbarch *loc_gdbarch = get_sal_arch (*sal);
+ struct gdbarch *loc_gdbarch = get_sal_arch (sal);
if (loc_gdbarch == NULL)
- loc_gdbarch = b->gdbarch;
+ loc_gdbarch = gdbarch;
/* Adjust the breakpoint's address prior to allocating a location.
- Once we call allocate_bp_location(), that mostly uninitialized
+ Once we call allocate_location(), that mostly uninitialized
location will be placed on the location chain. Adjustment of the
breakpoint may cause target_read_memory() to be called and we do
not want its scan of the location chain to find a breakpoint and
location that's only been partially initialized. */
adjusted_address = adjust_breakpoint_address (loc_gdbarch,
- sal->pc, b->type);
+ sal.pc, type);
/* Sort the locations by their ADDRESS. */
- loc = allocate_bp_location (b);
- for (tmp = &(b->loc); *tmp != NULL && (*tmp)->address <= adjusted_address;
+ new_loc = allocate_location ();
+ for (tmp = &(loc); *tmp != NULL && (*tmp)->address <= adjusted_address;
tmp = &((*tmp)->next))
;
- loc->next = *tmp;
- *tmp = loc;
-
- loc->requested_address = sal->pc;
- loc->address = adjusted_address;
- loc->pspace = sal->pspace;
- loc->probe.prob = sal->prob;
- loc->probe.objfile = sal->objfile;
- gdb_assert (loc->pspace != NULL);
- loc->section = sal->section;
- loc->gdbarch = loc_gdbarch;
- loc->line_number = sal->line;
- loc->symtab = sal->symtab;
- loc->symbol = sal->symbol;
- loc->msymbol = sal->msymbol;
- loc->objfile = sal->objfile;
-
- set_breakpoint_location_function (loc);
+ new_loc->next = *tmp;
+ *tmp = new_loc;
+
+ new_loc->requested_address = sal.pc;
+ new_loc->address = adjusted_address;
+ new_loc->pspace = sal.pspace;
+ new_loc->probe.prob = sal.prob;
+ new_loc->probe.objfile = sal.objfile;
+ gdb_assert (new_loc->pspace != NULL);
+ new_loc->section = sal.section;
+ new_loc->gdbarch = loc_gdbarch;
+ new_loc->line_number = sal.line;
+ new_loc->symtab = sal.symtab;
+ new_loc->symbol = sal.symbol;
+ new_loc->msymbol = sal.msymbol;
+ new_loc->objfile = sal.objfile;
+
+ set_breakpoint_location_function (new_loc);
/* While by definition, permanent breakpoints are already present in the
code, we don't mark the location as inserted. Normally one would expect
(If GDB later needs to continue execution past the permanent breakpoint,
it manually increments the PC, thus avoiding executing the breakpoint
instruction.) */
- if (bp_loc_is_permanent (loc))
- loc->permanent = 1;
+ if (bp_loc_is_permanent (new_loc))
+ new_loc->permanent = 1;
- return loc;
+ return new_loc;
}
\f
update_dprintf_command_list (b);
}
-/* Create a breakpoint with SAL as location. Use LOCATION
- as a description of the location, and COND_STRING
- as condition expression. If LOCATION is NULL then create an
- "address location" from the address in the SAL. */
-
-static void
-init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
- gdb::array_view<const symtab_and_line> sals,
- event_location_up &&location,
- gdb::unique_xmalloc_ptr<char> filter,
- gdb::unique_xmalloc_ptr<char> cond_string,
- gdb::unique_xmalloc_ptr<char> extra_string,
- enum bptype type, enum bpdisp disposition,
- int thread, int task, int ignore_count,
- const struct breakpoint_ops *ops, int from_tty,
- int enabled, int internal, unsigned flags,
- int display_canonical)
+code_breakpoint::code_breakpoint (struct gdbarch *gdbarch_,
+ enum bptype type_,
+ gdb::array_view<const symtab_and_line> sals,
+ location_spec_up &&locspec_,
+ gdb::unique_xmalloc_ptr<char> filter_,
+ 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 from_tty,
+ int enabled_, unsigned flags,
+ int display_canonical_)
+ : breakpoint (gdbarch_, type_)
{
int i;
gdb_assert (!sals.empty ());
- for (const auto &sal : sals)
- {
- struct bp_location *loc;
+ thread = thread_;
+ task = task_;
- if (from_tty)
- {
- struct gdbarch *loc_gdbarch = get_sal_arch (sal);
- if (!loc_gdbarch)
- loc_gdbarch = gdbarch;
+ cond_string = std::move (cond_string_);
+ extra_string = std::move (extra_string_);
+ ignore_count = ignore_count_;
+ enable_state = enabled_ ? bp_enabled : bp_disabled;
+ disposition = disposition_;
- describe_other_breakpoints (loc_gdbarch,
- sal.pspace, sal.pc, sal.section, thread);
- }
+ if (type == bp_static_tracepoint
+ || type == bp_static_marker_tracepoint)
+ {
+ auto *t = static_cast<struct tracepoint *> (this);
+ struct static_tracepoint_marker marker;
- if (&sal == &sals[0])
+ if (strace_marker_p (this))
{
- init_raw_breakpoint (b, gdbarch, sal, type, ops);
- b->thread = thread;
- b->task = task;
-
- b->cond_string = std::move (cond_string);
- b->extra_string = std::move (extra_string);
- b->ignore_count = ignore_count;
- b->enable_state = enabled ? bp_enabled : bp_disabled;
- b->disposition = disposition;
-
- if ((flags & CREATE_BREAKPOINT_FLAGS_INSERTED) != 0)
- b->loc->inserted = 1;
-
- if (type == bp_static_tracepoint)
- {
- struct tracepoint *t = (struct tracepoint *) b;
- struct static_tracepoint_marker marker;
-
- if (strace_marker_p (b))
- {
- /* We already know the marker exists, otherwise, we
- wouldn't see a sal for it. */
- const char *p
- = &event_location_to_string (b->location.get ())[3];
- const char *endp;
-
- p = skip_spaces (p);
+ /* We already know the marker exists, otherwise, we wouldn't
+ see a sal for it. */
+ const char *p = &location_spec_to_string (locspec_.get ())[3];
+ const char *endp;
- endp = skip_to_space (p);
+ p = skip_spaces (p);
- t->static_trace_marker_id.assign (p, endp - p);
+ endp = skip_to_space (p);
- gdb_printf (_("Probed static tracepoint "
- "marker \"%s\"\n"),
- t->static_trace_marker_id.c_str ());
- }
- else if (target_static_tracepoint_marker_at (sal.pc, &marker))
- {
- t->static_trace_marker_id = std::move (marker.str_id);
+ t->static_trace_marker_id.assign (p, endp - p);
- gdb_printf (_("Probed static tracepoint "
- "marker \"%s\"\n"),
- t->static_trace_marker_id.c_str ());
- }
- else
- warning (_("Couldn't determine the static "
- "tracepoint marker to probe"));
- }
+ gdb_printf (_("Probed static tracepoint marker \"%s\"\n"),
+ t->static_trace_marker_id.c_str ());
+ }
+ else if (target_static_tracepoint_marker_at (sals[0].pc, &marker))
+ {
+ t->static_trace_marker_id = std::move (marker.str_id);
- loc = b->loc;
+ gdb_printf (_("Probed static tracepoint marker \"%s\"\n"),
+ t->static_trace_marker_id.c_str ());
}
else
+ warning (_("Couldn't determine the static tracepoint marker to probe"));
+ }
+
+ for (const auto &sal : sals)
+ {
+ if (from_tty)
{
- loc = add_location_to_breakpoint (b, &sal);
- if ((flags & CREATE_BREAKPOINT_FLAGS_INSERTED) != 0)
- loc->inserted = 1;
+ struct gdbarch *loc_gdbarch = get_sal_arch (sal);
+ if (loc_gdbarch == nullptr)
+ loc_gdbarch = gdbarch;
+
+ describe_other_breakpoints (loc_gdbarch,
+ sal.pspace, sal.pc, sal.section, thread);
}
+ bp_location *new_loc = add_location (sal);
+ if ((flags & CREATE_BREAKPOINT_FLAGS_INSERTED) != 0)
+ new_loc->inserted = 1;
+
/* Do not set breakpoint locations conditions yet. As locations
are inserted, they get sorted based on their addresses. Let
the list stabilize to have reliable location numbers. */
command line, otherwise it's an error. */
if (type == bp_dprintf)
{
- if (b->extra_string)
- update_dprintf_command_list (b);
+ if (extra_string != nullptr)
+ update_dprintf_command_list (this);
else
error (_("Format string required"));
}
- else if (b->extra_string)
- error (_("Garbage '%s' at end of command"), b->extra_string.get ());
+ else if (extra_string != nullptr)
+ error (_("Garbage '%s' at end of command"), extra_string.get ());
}
-
/* The order of the locations is now stable. Set the location
condition using the location's number. */
int loc_num = 1;
- for (bp_location *loc : b->locations ())
+ for (bp_location *bl : locations ())
{
- if (b->cond_string != nullptr)
- set_breakpoint_location_condition (b->cond_string.get (), loc,
- b->number, loc_num);
+ if (cond_string != nullptr)
+ set_breakpoint_location_condition (cond_string.get (), bl,
+ number, loc_num);
++loc_num;
}
- b->display_canonical = display_canonical;
- if (location != NULL)
- b->location = std::move (location);
+ display_canonical = display_canonical_;
+ if (locspec_ != nullptr)
+ locspec = std::move (locspec_);
else
- b->location = new_address_location (b->loc->address, NULL, 0);
- b->filter = std::move (filter);
+ locspec = new_address_location_spec (this->loc->address, NULL, 0);
+ filter = std::move (filter_);
}
static void
create_breakpoint_sal (struct gdbarch *gdbarch,
gdb::array_view<const symtab_and_line> sals,
- event_location_up &&location,
+ location_spec_up &&locspec,
gdb::unique_xmalloc_ptr<char> filter,
gdb::unique_xmalloc_ptr<char> cond_string,
gdb::unique_xmalloc_ptr<char> extra_string,
enum bptype type, enum bpdisp disposition,
int thread, int task, int ignore_count,
- const struct breakpoint_ops *ops, int from_tty,
+ int from_tty,
int enabled, int internal, unsigned flags,
int display_canonical)
{
- std::unique_ptr<breakpoint> b = new_breakpoint_from_type (type);
-
- init_breakpoint_sal (b.get (), gdbarch,
- sals, std::move (location),
- std::move (filter),
- std::move (cond_string),
- std::move (extra_string),
- type, disposition,
- thread, task, ignore_count,
- ops, from_tty,
- enabled, internal, flags,
- display_canonical);
+ std::unique_ptr<code_breakpoint> b
+ = new_breakpoint_from_type (gdbarch,
+ type,
+ sals,
+ std::move (locspec),
+ std::move (filter),
+ std::move (cond_string),
+ std::move (extra_string),
+ disposition,
+ thread, task, ignore_count,
+ from_tty,
+ enabled, flags,
+ display_canonical);
install_breakpoint (internal, std::move (b), 0);
}
gdb::unique_xmalloc_ptr<char> extra_string,
enum bptype type, enum bpdisp disposition,
int thread, int task, int ignore_count,
- const struct breakpoint_ops *ops, int from_tty,
+ int from_tty,
int enabled, int internal, unsigned flags)
{
if (canonical->pre_expanded)
{
/* Note that 'location' can be NULL in the case of a plain
'break', without arguments. */
- event_location_up location
- = (canonical->location != NULL
- ? copy_event_location (canonical->location.get ()) : NULL);
+ location_spec_up locspec
+ = (canonical->locspec != nullptr
+ ? canonical->locspec->clone ()
+ : nullptr);
gdb::unique_xmalloc_ptr<char> filter_string
(lsal.canonical != NULL ? xstrdup (lsal.canonical) : NULL);
create_breakpoint_sal (gdbarch, lsal.sals,
- std::move (location),
+ std::move (locspec),
std::move (filter_string),
std::move (cond_string),
std::move (extra_string),
type, disposition,
- thread, task, ignore_count, ops,
+ thread, task, ignore_count,
from_tty, enabled, internal, flags,
canonical->special_display);
}
}
-/* Parse LOCATION which is assumed to be a SAL specification possibly
+/* Parse LOCSPEC which is assumed to be a SAL specification possibly
followed by conditionals. On return, SALS contains an array of SAL
- addresses found. LOCATION points to the end of the SAL (for
- linespec locations).
+ addresses found. LOCSPEC points to the end of the SAL (for
+ linespec locspecs).
The array and the line spec strings are allocated on the heap, it is
the caller's responsibility to free them. */
static void
-parse_breakpoint_sals (struct event_location *location,
+parse_breakpoint_sals (location_spec *locspec,
struct linespec_result *canonical)
{
struct symtab_and_line cursal;
- if (event_location_type (location) == LINESPEC_LOCATION)
+ if (location_spec_type (locspec) == LINESPEC_LOCATION_SPEC)
{
- const char *spec = get_linespec_location (location)->spec_string;
+ const char *spec = as_linespec_location_spec (locspec)->spec_string;
if (spec == NULL)
{
{
const char *spec = NULL;
- if (event_location_type (location) == LINESPEC_LOCATION)
- spec = get_linespec_location (location)->spec_string;
+ if (location_spec_type (locspec) == LINESPEC_LOCATION_SPEC)
+ spec = as_linespec_location_spec (locspec)->spec_string;
if (!cursal.symtab
|| (spec != NULL
&& strchr ("+-", spec[0]) != NULL
&& spec[1] != '['))
{
- decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, NULL,
+ decode_line_full (locspec, DECODE_LINE_FUNFIRSTLINE, NULL,
get_last_displayed_symtab (),
get_last_displayed_line (),
canonical, NULL, NULL);
}
}
- decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, NULL,
+ decode_line_full (locspec, DECODE_LINE_FUNFIRSTLINE, NULL,
cursal.symtab, cursal.line, canonical, NULL, NULL);
}
according to IS_TRACEPOINT. */
static const struct breakpoint_ops *
-breakpoint_ops_for_event_location_type (enum event_location_type location_type,
- bool is_tracepoint)
+breakpoint_ops_for_location_spec_type (enum location_spec_type locspec_type,
+ bool is_tracepoint)
{
if (is_tracepoint)
{
- if (location_type == PROBE_LOCATION)
+ if (locspec_type == PROBE_LOCATION_SPEC)
return &tracepoint_probe_breakpoint_ops;
else
- return &vtable_breakpoint_ops;
+ return &code_breakpoint_ops;
}
else
{
- if (location_type == PROBE_LOCATION)
+ if (locspec_type == PROBE_LOCATION_SPEC)
return &bkpt_probe_breakpoint_ops;
else
- return &bkpt_breakpoint_ops;
+ return &code_breakpoint_ops;
}
}
/* See breakpoint.h. */
const struct breakpoint_ops *
-breakpoint_ops_for_event_location (const struct event_location *location,
- bool is_tracepoint)
+breakpoint_ops_for_location_spec (const location_spec *locspec,
+ bool is_tracepoint)
{
- if (location != nullptr)
- return breakpoint_ops_for_event_location_type
- (event_location_type (location), is_tracepoint);
- return is_tracepoint ? &vtable_breakpoint_ops : &bkpt_breakpoint_ops;
+ if (locspec != nullptr)
+ return (breakpoint_ops_for_location_spec_type
+ (location_spec_type (locspec), is_tracepoint));
+ return &code_breakpoint_ops;
}
/* See breakpoint.h. */
int
create_breakpoint (struct gdbarch *gdbarch,
- struct event_location *location,
+ location_spec *locspec,
const char *cond_string,
int thread, const char *extra_string,
bool force_condition, int parse_extra,
try
{
- ops->create_sals_from_location (location, &canonical, type_wanted);
+ ops->create_sals_from_location_spec (locspec, &canonical);
}
catch (const gdb_exception_error &e)
{
std::move (extra_string_copy),
type_wanted,
tempflag ? disp_del : disp_donttouch,
- thread, task, ignore_count, ops,
+ thread, task, ignore_count,
from_tty, enabled, internal, flags);
}
else
{
- std::unique_ptr <breakpoint> b = new_breakpoint_from_type (type_wanted);
-
- init_raw_breakpoint_without_location (b.get (), gdbarch, type_wanted, ops);
- b->location = copy_event_location (location);
+ std::unique_ptr <breakpoint> b = new_breakpoint_from_type (gdbarch,
+ type_wanted);
+ b->locspec = locspec->clone ();
if (parse_extra)
b->cond_string = NULL;
? bp_hardware_breakpoint
: bp_breakpoint);
- event_location_up location = string_to_event_location (&arg, current_language);
- const struct breakpoint_ops *ops = breakpoint_ops_for_event_location
- (location.get (), false /* is_tracepoint */);
+ location_spec_up locspec = string_to_location_spec (&arg, current_language);
+ const struct breakpoint_ops *ops
+ = breakpoint_ops_for_location_spec (locspec.get (),
+ false /* is_tracepoint */);
create_breakpoint (get_current_arch (),
- location.get (),
+ locspec.get (),
NULL, 0, arg, false, 1 /* parse arg */,
tempflag, type_wanted,
0 /* Ignore count */,
static void
dprintf_command (const char *arg, int from_tty)
{
- event_location_up location = string_to_event_location (&arg, current_language);
+ location_spec_up locspec = string_to_location_spec (&arg, current_language);
/* If non-NULL, ARG should have been advanced past the location;
the next character must be ','. */
}
create_breakpoint (get_current_arch (),
- location.get (),
+ locspec.get (),
NULL, 0, arg, false, 1 /* parse arg */,
0, bp_dprintf,
0 /* Ignore count */,
pending_break_support,
- &dprintf_breakpoint_ops,
+ &code_breakpoint_ops,
from_tty,
1 /* enabled */,
0 /* internal */,
error (_("May only run agent-printf on the target"));
}
-/* Implement the "breakpoint_hit" breakpoint_ops method for
- ranged breakpoints. */
+/* Implement the "breakpoint_hit" method for ranged breakpoints. */
-static int
-breakpoint_hit_ranged_breakpoint (const struct bp_location *bl,
- const address_space *aspace,
- CORE_ADDR bp_addr,
- const target_waitstatus &ws)
+int
+ranged_breakpoint::breakpoint_hit (const struct bp_location *bl,
+ const address_space *aspace,
+ CORE_ADDR bp_addr,
+ const target_waitstatus &ws)
{
if (ws.kind () != TARGET_WAITKIND_STOPPED
|| ws.sig () != GDB_SIGNAL_TRAP)
bl->length, aspace, bp_addr);
}
-/* Implement the "resources_needed" breakpoint_ops method for
- ranged breakpoints. */
+/* Implement the "resources_needed" method for ranged breakpoints. */
-static int
-resources_needed_ranged_breakpoint (const struct bp_location *bl)
+int
+ranged_breakpoint::resources_needed (const struct bp_location *bl)
{
return target_ranged_break_num_registers ();
}
-/* Implement the "print_it" breakpoint_ops method for
- ranged breakpoints. */
+/* Implement the "print_it" method for ranged breakpoints. */
-static enum print_stop_action
-print_it_ranged_breakpoint (bpstat *bs)
+enum print_stop_action
+ranged_breakpoint::print_it (const bpstat *bs) const
{
- struct breakpoint *b = bs->breakpoint_at;
- struct bp_location *bl = b->loc;
+ struct bp_location *bl = loc;
struct ui_out *uiout = current_uiout;
- gdb_assert (b->type == bp_hardware_breakpoint);
+ gdb_assert (type == bp_hardware_breakpoint);
/* Ranged breakpoints have only one location. */
gdb_assert (bl && bl->next == NULL);
- annotate_breakpoint (b->number);
+ annotate_breakpoint (number);
maybe_print_thread_hit_breakpoint (uiout);
- if (b->disposition == disp_del)
+ if (disposition == disp_del)
uiout->text ("Temporary ranged breakpoint ");
else
uiout->text ("Ranged breakpoint ");
{
uiout->field_string ("reason",
async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
- uiout->field_string ("disp", bpdisp_text (b->disposition));
+ uiout->field_string ("disp", bpdisp_text (disposition));
}
- uiout->field_signed ("bkptno", b->number);
+ uiout->field_signed ("bkptno", number);
uiout->text (", ");
return PRINT_SRC_AND_LOC;
}
-/* Implement the "print_one" breakpoint_ops method for
- ranged breakpoints. */
+/* Implement the "print_one" method for ranged breakpoints. */
-static bool
-print_one_ranged_breakpoint (struct breakpoint *b,
- struct bp_location **last_loc)
+bool
+ranged_breakpoint::print_one (bp_location **last_loc) const
{
- struct bp_location *bl = b->loc;
+ struct bp_location *bl = loc;
struct value_print_options opts;
struct ui_out *uiout = current_uiout;
by print_one_detail_ranged_breakpoint. */
uiout->field_skip ("addr");
annotate_field (5);
- print_breakpoint_location (b, bl);
+ print_breakpoint_location (this, bl);
*last_loc = bl;
return true;
}
-/* Implement the "print_one_detail" breakpoint_ops method for
- ranged breakpoints. */
+/* Implement the "print_one_detail" method for ranged breakpoints. */
-static void
-print_one_detail_ranged_breakpoint (const struct breakpoint *b,
- struct ui_out *uiout)
+void
+ranged_breakpoint::print_one_detail (struct ui_out *uiout) const
{
CORE_ADDR address_start, address_end;
- struct bp_location *bl = b->loc;
+ struct bp_location *bl = loc;
string_file stb;
gdb_assert (bl);
uiout->text ("\n");
}
-/* Implement the "print_mention" breakpoint_ops method for
- ranged breakpoints. */
+/* Implement the "print_mention" method for ranged breakpoints. */
-static void
-print_mention_ranged_breakpoint (struct breakpoint *b)
+void
+ranged_breakpoint::print_mention () const
{
- struct bp_location *bl = b->loc;
+ struct bp_location *bl = loc;
struct ui_out *uiout = current_uiout;
gdb_assert (bl);
- gdb_assert (b->type == bp_hardware_breakpoint);
+ gdb_assert (type == bp_hardware_breakpoint);
uiout->message (_("Hardware assisted ranged breakpoint %d from %s to %s."),
- b->number, paddress (bl->gdbarch, bl->address),
+ number, paddress (bl->gdbarch, bl->address),
paddress (bl->gdbarch, bl->address + bl->length - 1));
}
-/* Implement the "print_recreate" breakpoint_ops method for
- ranged breakpoints. */
+/* Implement the "print_recreate" method for ranged breakpoints. */
-static void
-print_recreate_ranged_breakpoint (struct breakpoint *b, struct ui_file *fp)
+void
+ranged_breakpoint::print_recreate (struct ui_file *fp) const
{
gdb_printf (fp, "break-range %s, %s",
- event_location_to_string (b->location.get ()),
- event_location_to_string (b->location_range_end.get ()));
- print_recreate_thread (b, fp);
+ location_spec_to_string (locspec.get ()),
+ location_spec_to_string (locspec_range_end.get ()));
+ print_recreate_thread (fp);
}
-/* The breakpoint_ops structure to be used in ranged breakpoints. */
-
-static struct breakpoint_ops ranged_breakpoint_ops;
-
/* Find the address where the end of the breakpoint range should be
placed, given the SAL of the end of the range. This is so that if
the user provides a line number, the end of the range is set to the
struct linespec_result canonical_start, canonical_end;
int bp_count, can_use_bp, length;
CORE_ADDR end;
- struct breakpoint *b;
/* We don't support software ranged breakpoints. */
if (target_ranged_break_num_registers () < 0)
error(_("No address range specified."));
arg_start = arg;
- event_location_up start_location = string_to_event_location (&arg,
- current_language);
- parse_breakpoint_sals (start_location.get (), &canonical_start);
+ location_spec_up start_locspec
+ = string_to_location_spec (&arg, current_language);
+ parse_breakpoint_sals (start_locspec.get (), &canonical_start);
if (arg[0] != ',')
error (_("Too few arguments."));
arg++; /* Skip the comma. */
arg = skip_spaces (arg);
- /* Parse the end location. */
+ /* Parse the end location specification. */
arg_start = arg;
/* We call decode_line_full directly here instead of using
- parse_breakpoint_sals because we need to specify the start location's
- symtab and line as the default symtab and line for the end of the
- range. This makes it possible to have ranges like "foo.c:27, +14",
- where +14 means 14 lines from the start location. */
- event_location_up end_location = string_to_event_location (&arg,
- current_language);
- decode_line_full (end_location.get (), DECODE_LINE_FUNFIRSTLINE, NULL,
+ parse_breakpoint_sals because we need to specify the start
+ location spec's symtab and line as the default symtab and line
+ for the end of the range. This makes it possible to have ranges
+ like "foo.c:27, +14", where +14 means 14 lines from the start
+ location spec. */
+ location_spec_up end_locspec
+ = string_to_location_spec (&arg, current_language);
+ decode_line_full (end_locspec.get (), DECODE_LINE_FUNFIRSTLINE, NULL,
sal_start.symtab, sal_start.line,
&canonical_end, NULL, NULL);
return;
}
- /* Now set up the breakpoint. */
- b = set_raw_breakpoint (get_current_arch (), sal_start,
- bp_hardware_breakpoint, &ranged_breakpoint_ops);
- set_breakpoint_count (breakpoint_count + 1);
- b->number = breakpoint_count;
- b->disposition = disp_donttouch;
- b->location = std::move (start_location);
- b->location_range_end = std::move (end_location);
- b->loc->length = length;
+ /* Now set up the breakpoint and install it. */
- mention (b);
- gdb::observers::breakpoint_created.notify (b);
- update_global_location_list (UGLL_MAY_INSERT);
+ std::unique_ptr<breakpoint> br
+ (new ranged_breakpoint (get_current_arch (),
+ sal_start, length,
+ std::move (start_locspec),
+ std::move (end_locspec)));
+
+ install_breakpoint (false, std::move (br), true);
}
/* Return non-zero if EXP is verified as constant. Returned zero
/* Implement the "works_in_software_mode" method for hardware
watchpoints. */
-int
+bool
watchpoint::works_in_software_mode () const
{
/* Read and access watchpoints only work with hardware support. */
}
enum print_stop_action
-watchpoint::print_it (bpstat *bs)
+watchpoint::print_it (const bpstat *bs) const
{
struct breakpoint *b;
enum print_stop_action result;
/* Implement the "print_mention" method for hardware watchpoints. */
void
-watchpoint::print_mention ()
+watchpoint::print_mention () const
{
struct ui_out *uiout = current_uiout;
const char *tuple_name;
/* Implement the "print_recreate" method for watchpoints. */
void
-watchpoint::print_recreate (struct ui_file *fp)
+watchpoint::print_recreate (struct ui_file *fp) const
{
switch (type)
{
}
gdb_printf (fp, " %s", exp_string.get ());
- print_recreate_thread (this, fp);
+ print_recreate_thread (fp);
}
/* Implement the "explains_signal" method for watchpoints. */
-int
+bool
watchpoint::explains_signal (enum gdb_signal sig)
{
/* A software watchpoint cannot cause a signal other than
GDB_SIGNAL_TRAP. */
if (type == bp_watchpoint && sig != GDB_SIGNAL_TRAP)
- return 0;
+ return false;
- return 1;
+ return true;
}
struct masked_watchpoint : public watchpoint
{
+ using watchpoint::watchpoint;
+
int insert_location (struct bp_location *) override;
int remove_location (struct bp_location *,
enum remove_bp_reason reason) override;
int resources_needed (const struct bp_location *) override;
- int works_in_software_mode () const override;
- enum print_stop_action print_it (struct bpstat *bs) override;
+ bool works_in_software_mode () const override;
+ enum print_stop_action print_it (const bpstat *bs) const override;
void print_one_detail (struct ui_out *) const override;
- void print_mention () override;
- void print_recreate (struct ui_file *fp) override;
+ void print_mention () const override;
+ void print_recreate (struct ui_file *fp) const override;
};
/* Implement the "insert" method for masked hardware watchpoints. */
/* Implement the "works_in_software_mode" method for masked hardware
watchpoints. */
-int
+bool
masked_watchpoint::works_in_software_mode () const
{
- return 0;
+ return false;
}
/* Implement the "print_it" method for masked hardware
watchpoints. */
enum print_stop_action
-masked_watchpoint::print_it (bpstat *bs)
+masked_watchpoint::print_it (const bpstat *bs) const
{
struct breakpoint *b = bs->breakpoint_at;
struct ui_out *uiout = current_uiout;
watchpoints. */
void
-masked_watchpoint::print_mention ()
+masked_watchpoint::print_mention () const
{
struct ui_out *uiout = current_uiout;
const char *tuple_name;
watchpoints. */
void
-masked_watchpoint::print_recreate (struct ui_file *fp)
+masked_watchpoint::print_recreate (struct ui_file *fp) const
{
switch (type)
{
gdb_printf (fp, " %s mask 0x%s", exp_string.get (),
phex (hw_wp_mask, sizeof (CORE_ADDR)));
- print_recreate_thread (this, fp);
+ print_recreate_thread (fp);
}
/* Tell whether the given watchpoint is a masked hardware watchpoint. */
scope_breakpoint
= create_internal_breakpoint (caller_arch, caller_pc,
- bp_watchpoint_scope,
- &vtable_breakpoint_ops);
+ bp_watchpoint_scope);
/* create_internal_breakpoint could invalidate WP_FRAME. */
wp_frame = NULL;
std::unique_ptr<watchpoint> w;
if (use_mask)
- w.reset (new masked_watchpoint ());
+ w.reset (new masked_watchpoint (nullptr, bp_type));
else
- w.reset (new watchpoint ());
- init_raw_breakpoint_without_location (w.get (), nullptr, bp_type,
- &vtable_breakpoint_ops);
+ w.reset (new watchpoint (nullptr, bp_type));
w->thread = thread;
w->task = task;
/* Set a breakpoint where the user wants it and at return from
this function. */
- event_location_up location = string_to_event_location (&arg, current_language);
+ location_spec_up locspec = string_to_location_spec (&arg, current_language);
std::vector<symtab_and_line> sals
= (last_displayed_sal_is_valid ()
- ? decode_line_1 (location.get (), DECODE_LINE_FUNFIRSTLINE, NULL,
+ ? decode_line_1 (locspec.get (), DECODE_LINE_FUNFIRSTLINE, NULL,
get_last_displayed_symtab (),
get_last_displayed_line ())
- : decode_line_1 (location.get (), DECODE_LINE_FUNFIRSTLINE,
+ : decode_line_1 (locspec.get (), DECODE_LINE_FUNFIRSTLINE,
NULL, NULL, 0));
if (sals.empty ())
proceed (-1, GDB_SIGNAL_DEFAULT);
}
-void
-init_ada_exception_breakpoint (struct breakpoint *b,
- struct gdbarch *gdbarch,
- struct symtab_and_line sal,
- const char *addr_string,
- const struct breakpoint_ops *ops,
- int tempflag,
- int enabled,
- int from_tty)
-{
- if (from_tty)
- {
- struct gdbarch *loc_gdbarch = get_sal_arch (sal);
- if (!loc_gdbarch)
- loc_gdbarch = gdbarch;
-
- describe_other_breakpoints (loc_gdbarch,
- sal.pspace, sal.pc, sal.section, -1);
- /* FIXME: brobecker/2006-12-28: Actually, re-implement a special
- version for exception catchpoints, because two catchpoints
- used for different exception names will use the same address.
- In this case, a "breakpoint ... also set at..." warning is
- unproductive. Besides, the warning phrasing is also a bit
- inappropriate, we should use the word catchpoint, and tell
- the user what type of catchpoint it is. The above is good
- enough for now, though. */
- }
-
- init_raw_breakpoint (b, gdbarch, sal, bp_catchpoint, ops);
-
- b->enable_state = enabled ? bp_enabled : bp_disabled;
- b->disposition = tempflag ? disp_del : disp_donttouch;
- b->location = string_to_event_location (&addr_string,
- language_def (language_ada));
- b->language = language_ada;
-}
-
\f
/* Compare two breakpoints and return a strcmp-like result. */
return 0;
}
-/* Helper for breakpoint and tracepoint breakpoint_ops->mention
+/* Helper for breakpoint and tracepoint breakpoint->mention
callbacks. */
static void
-say_where (struct breakpoint *b)
+say_where (const breakpoint *b)
{
struct value_print_options opts;
if (b->extra_string == NULL)
{
gdb_printf (_(" (%s) pending."),
- event_location_to_string (b->location.get ()));
+ location_spec_to_string (b->locspec.get ()));
}
else if (b->type == bp_dprintf)
{
gdb_printf (_(" (%s,%s) pending."),
- event_location_to_string (b->location.get ()),
+ location_spec_to_string (b->locspec.get ()),
b->extra_string.get ());
}
else
{
gdb_printf (_(" (%s %s) pending."),
- event_location_to_string (b->location.get ()),
+ location_spec_to_string (b->locspec.get ()),
b->extra_string.get ());
}
}
different file name, and this at least reflects the
real situation somewhat. */
gdb_printf (": %s.",
- event_location_to_string (b->location.get ()));
+ location_spec_to_string (b->locspec.get ()));
}
if (b->loc->next)
/* See breakpoint.h. */
-bp_location_range breakpoint::locations ()
+bp_location_range breakpoint::locations () const
{
return bp_location_range (this->loc);
}
-static struct bp_location *
-base_breakpoint_allocate_location (struct breakpoint *self)
-{
- return new bp_location (self);
-}
-
struct bp_location *
breakpoint::allocate_location ()
{
return new bp_location (this);
}
-static void
-base_breakpoint_re_set (struct breakpoint *b)
-{
- /* Nothing to re-set. */
-}
-
#define internal_error_pure_virtual_called() \
gdb_assert_not_reached ("pure virtual function called")
-static int
-base_breakpoint_insert_location (struct bp_location *bl)
-{
- internal_error_pure_virtual_called ();
-}
-
int
breakpoint::insert_location (struct bp_location *bl)
{
internal_error_pure_virtual_called ();
}
-static int
-base_breakpoint_remove_location (struct bp_location *bl,
- enum remove_bp_reason reason)
-{
- internal_error_pure_virtual_called ();
-}
-
int
breakpoint::remove_location (struct bp_location *bl,
enum remove_bp_reason reason)
internal_error_pure_virtual_called ();
}
-static int
-base_breakpoint_breakpoint_hit (const struct bp_location *bl,
- const address_space *aspace,
- CORE_ADDR bp_addr,
- const target_waitstatus &ws)
-{
- internal_error_pure_virtual_called ();
-}
-
int
breakpoint::breakpoint_hit (const struct bp_location *bl,
const address_space *aspace,
internal_error_pure_virtual_called ();
}
-static void
-base_breakpoint_check_status (bpstat *bs)
-{
- /* Always stop. */
-}
-
-/* A "works_in_software_mode" breakpoint_ops method that just internal
- errors. */
-
-static int
-base_breakpoint_works_in_software_mode (const struct breakpoint *b)
-{
- internal_error_pure_virtual_called ();
-}
-
-int
-breakpoint::works_in_software_mode () const
-{
- internal_error_pure_virtual_called ();
-}
-
-/* A "resources_needed" breakpoint_ops method that just internal
- errors. */
-
-static int
-base_breakpoint_resources_needed (const struct bp_location *bl)
-{
- internal_error_pure_virtual_called ();
-}
-
int
breakpoint::resources_needed (const struct bp_location *bl)
{
internal_error_pure_virtual_called ();
}
-static enum print_stop_action
-base_breakpoint_print_it (bpstat *bs)
-{
- internal_error_pure_virtual_called ();
-}
-
enum print_stop_action
-breakpoint::print_it (bpstat *bs)
-{
- internal_error_pure_virtual_called ();
-}
-
-static bool
-base_breakpoint_print_one (struct breakpoint *, struct bp_location **)
-{
- return false;
-}
-
-static void
-base_breakpoint_print_one_detail (const struct breakpoint *self,
- struct ui_out *uiout)
-{
- /* nothing */
-}
-
-static void
-base_breakpoint_print_mention (struct breakpoint *b)
+breakpoint::print_it (const bpstat *bs) const
{
internal_error_pure_virtual_called ();
}
void
-breakpoint::print_mention ()
-{
- internal_error_pure_virtual_called ();
-}
-
-static void
-base_breakpoint_print_recreate (struct breakpoint *b, struct ui_file *fp)
+breakpoint::print_mention () const
{
internal_error_pure_virtual_called ();
}
void
-breakpoint::print_recreate (struct ui_file *fp)
-{
- internal_error_pure_virtual_called ();
-}
-
-static void
-base_breakpoint_create_sals_from_location
- (struct event_location *location,
- struct linespec_result *canonical,
- enum bptype type_wanted)
-{
- internal_error_pure_virtual_called ();
-}
-
-static void
-base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch,
- struct linespec_result *c,
- gdb::unique_xmalloc_ptr<char> cond_string,
- gdb::unique_xmalloc_ptr<char> extra_string,
- enum bptype type_wanted,
- enum bpdisp disposition,
- int thread,
- int task, int ignore_count,
- const struct breakpoint_ops *o,
- int from_tty, int enabled,
- int internal, unsigned flags)
-{
- internal_error_pure_virtual_called ();
-}
-
-static std::vector<symtab_and_line>
-base_breakpoint_decode_location (struct breakpoint *b,
- struct event_location *location,
- struct program_space *search_pspace)
+breakpoint::print_recreate (struct ui_file *fp) const
{
internal_error_pure_virtual_called ();
}
std::vector<symtab_and_line>
-breakpoint::decode_location (struct event_location *location,
- struct program_space *search_pspace)
+breakpoint::decode_location_spec (location_spec *locspec,
+ program_space *search_pspace)
{
internal_error_pure_virtual_called ();
}
-/* The default 'explains_signal' method. */
-
-static int
-base_breakpoint_explains_signal (struct breakpoint *b, enum gdb_signal sig)
-{
- return 1;
-}
-
-/* The default "after_condition_true" method. */
-
-static void
-base_breakpoint_after_condition_true (struct bpstat *bs)
-{
- /* Nothing to do. */
-}
-
-struct breakpoint_ops base_breakpoint_ops =
-{
- base_breakpoint_allocate_location,
- base_breakpoint_re_set,
- base_breakpoint_insert_location,
- base_breakpoint_remove_location,
- base_breakpoint_breakpoint_hit,
- base_breakpoint_check_status,
- base_breakpoint_resources_needed,
- base_breakpoint_works_in_software_mode,
- base_breakpoint_print_it,
- base_breakpoint_print_one,
- base_breakpoint_print_one_detail,
- base_breakpoint_print_mention,
- base_breakpoint_print_recreate,
- base_breakpoint_create_sals_from_location,
- base_breakpoint_create_breakpoints_sal,
- base_breakpoint_decode_location,
- base_breakpoint_explains_signal,
- base_breakpoint_after_condition_true,
-};
-
-struct breakpoint_ops vtable_breakpoint_ops =
-{
- [] (struct breakpoint *b) { return b->allocate_location (); },
- [] (struct breakpoint *b) { b->re_set (); },
- [] (struct bp_location *l)
- {
- return l->owner->insert_location (l);
- },
- [] (struct bp_location *l, enum remove_bp_reason reason)
- {
- return l->owner->remove_location (l, reason);
- },
- [] (const struct bp_location *bl,
- const address_space *aspace,
- CORE_ADDR bp_addr,
- const target_waitstatus &ws)
- {
- return bl->owner->breakpoint_hit (bl, aspace, bp_addr, ws);
- },
- [] (struct bpstat *bs) { bs->breakpoint_at->check_status (bs); },
- [] (const struct bp_location *bl)
- { return bl->owner->resources_needed (bl); },
- [] (const struct breakpoint *b)
- { return b->works_in_software_mode (); },
- [] (struct bpstat *bs)
- { return bs->breakpoint_at->print_it (bs); },
- [] (struct breakpoint *b, struct bp_location **bl)
- { return b->print_one (bl); },
- [] (const struct breakpoint *b, struct ui_out *out)
- { b->print_one_detail (out); },
- [] (struct breakpoint *b) { b->print_mention (); },
- [] (struct breakpoint *b, struct ui_file *fp)
- { b->print_recreate (fp); },
- create_sals_from_location_default,
- create_breakpoints_sal_default,
- [] (struct breakpoint *b,
- struct event_location *location,
- struct program_space *search_pspace)
- { return b->decode_location (location, search_pspace); },
- [] (struct breakpoint *b, enum gdb_signal s)
- { return b->explains_signal (s); },
- [] (struct bpstat *bs)
- { bs->breakpoint_at->after_condition_true (bs); }
-};
-
/* Default breakpoint_ops methods. */
void
-base_breakpoint::re_set ()
+code_breakpoint::re_set ()
{
/* FIXME: is this still reachable? */
- if (breakpoint_event_location_empty_p (this))
+ if (breakpoint_location_spec_empty_p (this))
{
/* Anything without a location can't be re-set. */
delete_breakpoint (this);
}
int
-base_breakpoint::insert_location (struct bp_location *bl)
+code_breakpoint::insert_location (struct bp_location *bl)
{
CORE_ADDR addr = bl->target_info.reqstd_address;
bl->target_info.kind = breakpoint_kind (bl, &addr);
bl->target_info.placed_address = addr;
+ int result;
if (bl->loc_type == bp_loc_hardware_breakpoint)
- return target_insert_hw_breakpoint (bl->gdbarch, &bl->target_info);
+ result = target_insert_hw_breakpoint (bl->gdbarch, &bl->target_info);
else
- return target_insert_breakpoint (bl->gdbarch, &bl->target_info);
+ result = target_insert_breakpoint (bl->gdbarch, &bl->target_info);
+
+ if (result == 0 && bl->probe.prob != nullptr)
+ {
+ /* The insertion was successful, now let's set the probe's semaphore
+ if needed. */
+ bl->probe.prob->set_semaphore (bl->probe.objfile, bl->gdbarch);
+ }
+
+ return result;
}
int
-base_breakpoint::remove_location (struct bp_location *bl,
+code_breakpoint::remove_location (struct bp_location *bl,
enum remove_bp_reason reason)
{
+ if (bl->probe.prob != nullptr)
+ {
+ /* Let's clear the semaphore before removing the location. */
+ bl->probe.prob->clear_semaphore (bl->probe.objfile, bl->gdbarch);
+ }
+
if (bl->loc_type == bp_loc_hardware_breakpoint)
return target_remove_hw_breakpoint (bl->gdbarch, &bl->target_info);
else
}
int
-base_breakpoint::breakpoint_hit (const struct bp_location *bl,
+code_breakpoint::breakpoint_hit (const struct bp_location *bl,
const address_space *aspace,
CORE_ADDR bp_addr,
const target_waitstatus &ws)
return 1;
}
-static int
-dprintf_breakpoint_hit (const struct bp_location *bl,
- const address_space *aspace, CORE_ADDR bp_addr,
- const target_waitstatus &ws)
+int
+dprintf_breakpoint::breakpoint_hit (const struct bp_location *bl,
+ const address_space *aspace,
+ CORE_ADDR bp_addr,
+ const target_waitstatus &ws)
{
if (dprintf_style == dprintf_style_agent
&& target_can_run_breakpoint_commands ())
return 0;
}
- return bl->owner->breakpoint_hit (bl, aspace, bp_addr, ws);
+ return this->ordinary_breakpoint::breakpoint_hit (bl, aspace, bp_addr, ws);
}
-static int
-bkpt_resources_needed (const struct bp_location *bl)
+int
+ordinary_breakpoint::resources_needed (const struct bp_location *bl)
{
- gdb_assert (bl->owner->type == bp_hardware_breakpoint);
+ gdb_assert (type == bp_hardware_breakpoint);
return 1;
}
-static enum print_stop_action
-bkpt_print_it (bpstat *bs)
+enum print_stop_action
+ordinary_breakpoint::print_it (const bpstat *bs) const
{
- struct breakpoint *b;
const struct bp_location *bl;
int bp_temp;
struct ui_out *uiout = current_uiout;
- gdb_assert (bs->bp_location_at != NULL);
-
bl = bs->bp_location_at.get ();
- b = bs->breakpoint_at;
- bp_temp = b->disposition == disp_del;
+ bp_temp = disposition == disp_del;
if (bl->address != bl->requested_address)
breakpoint_adjustment_warning (bl->requested_address,
bl->address,
- b->number, 1);
- annotate_breakpoint (b->number);
+ number, 1);
+ annotate_breakpoint (number);
maybe_print_thread_hit_breakpoint (uiout);
if (uiout->is_mi_like_p ())
{
uiout->field_string ("reason",
async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
- uiout->field_string ("disp", bpdisp_text (b->disposition));
+ uiout->field_string ("disp", bpdisp_text (disposition));
}
if (bp_temp)
uiout->message ("Temporary breakpoint %pF, ",
- signed_field ("bkptno", b->number));
+ signed_field ("bkptno", number));
else
uiout->message ("Breakpoint %pF, ",
- signed_field ("bkptno", b->number));
+ signed_field ("bkptno", number));
return PRINT_SRC_AND_LOC;
}
-static void
-bkpt_print_mention (struct breakpoint *b)
+void
+ordinary_breakpoint::print_mention () const
{
if (current_uiout->is_mi_like_p ())
return;
- switch (b->type)
+ switch (type)
{
case bp_breakpoint:
case bp_gnu_ifunc_resolver:
- if (b->disposition == disp_del)
+ if (disposition == disp_del)
gdb_printf (_("Temporary breakpoint"));
else
gdb_printf (_("Breakpoint"));
- gdb_printf (_(" %d"), b->number);
- if (b->type == bp_gnu_ifunc_resolver)
+ gdb_printf (_(" %d"), number);
+ if (type == bp_gnu_ifunc_resolver)
gdb_printf (_(" at gnu-indirect-function resolver"));
break;
case bp_hardware_breakpoint:
- gdb_printf (_("Hardware assisted breakpoint %d"), b->number);
+ gdb_printf (_("Hardware assisted breakpoint %d"), number);
break;
case bp_dprintf:
- gdb_printf (_("Dprintf %d"), b->number);
+ gdb_printf (_("Dprintf %d"), number);
break;
}
- say_where (b);
+ say_where (this);
}
-static void
-bkpt_print_recreate (struct breakpoint *tp, struct ui_file *fp)
+void
+ordinary_breakpoint::print_recreate (struct ui_file *fp) const
{
- if (tp->type == bp_breakpoint && tp->disposition == disp_del)
+ if (type == bp_breakpoint && disposition == disp_del)
gdb_printf (fp, "tbreak");
- else if (tp->type == bp_breakpoint)
+ else if (type == bp_breakpoint)
gdb_printf (fp, "break");
- else if (tp->type == bp_hardware_breakpoint
- && tp->disposition == disp_del)
+ else if (type == bp_hardware_breakpoint
+ && disposition == disp_del)
gdb_printf (fp, "thbreak");
- else if (tp->type == bp_hardware_breakpoint)
+ else if (type == bp_hardware_breakpoint)
gdb_printf (fp, "hbreak");
else
internal_error (__FILE__, __LINE__,
- _("unhandled breakpoint type %d"), (int) tp->type);
+ _("unhandled breakpoint type %d"), (int) type);
- gdb_printf (fp, " %s",
- event_location_to_string (tp->location.get ()));
+ gdb_printf (fp, " %s", location_spec_to_string (locspec.get ()));
/* Print out extra_string if this breakpoint is pending. It might
contain, for example, conditions that were set by the user. */
- if (tp->loc == NULL && tp->extra_string != NULL)
- gdb_printf (fp, " %s", tp->extra_string.get ());
+ if (loc == NULL && extra_string != NULL)
+ gdb_printf (fp, " %s", extra_string.get ());
- print_recreate_thread (tp, fp);
+ print_recreate_thread (fp);
}
std::vector<symtab_and_line>
-base_breakpoint::decode_location (struct event_location *location,
- struct program_space *search_pspace)
+code_breakpoint::decode_location_spec (location_spec *locspec,
+ program_space *search_pspace)
{
- return decode_location_default (this, location, search_pspace);
+ if (location_spec_type (locspec) == PROBE_LOCATION_SPEC)
+ return bkpt_probe_decode_location_spec (this, locspec, search_pspace);
+
+ return decode_location_spec_default (this, locspec, search_pspace);
}
/* Virtual table for internal breakpoints. */
}
enum print_stop_action
-internal_breakpoint::print_it (bpstat *bs)
+internal_breakpoint::print_it (const bpstat *bs) const
{
switch (type)
{
}
void
-internal_breakpoint::print_mention ()
+internal_breakpoint::print_mention () const
{
/* Nothing to mention. These breakpoints are internal. */
}
}
enum print_stop_action
-momentary_breakpoint::print_it (bpstat *bs)
+momentary_breakpoint::print_it (const bpstat *bs) const
{
return PRINT_UNKNOWN;
}
void
-momentary_breakpoint::print_mention ()
+momentary_breakpoint::print_mention () const
{
/* Nothing to mention. These breakpoints are internal. */
}
tp->initiating_frame = null_frame_id;
}
-/* Specific methods for probe breakpoints. */
-
-static int
-bkpt_probe_insert_location (struct bp_location *bl)
-{
- int v = bl->owner->insert_location (bl);
-
- if (v == 0)
- {
- /* The insertion was successful, now let's set the probe's semaphore
- if needed. */
- bl->probe.prob->set_semaphore (bl->probe.objfile, bl->gdbarch);
- }
-
- return v;
-}
-
-static int
-bkpt_probe_remove_location (struct bp_location *bl,
- enum remove_bp_reason reason)
-{
- /* Let's clear the semaphore before removing the location. */
- bl->probe.prob->clear_semaphore (bl->probe.objfile, bl->gdbarch);
-
- return bl->owner->remove_location (bl, reason);
-}
-
static void
-bkpt_probe_create_sals_from_location (struct event_location *location,
- struct linespec_result *canonical,
- enum bptype type_wanted)
+bkpt_probe_create_sals_from_location_spec (location_spec *locspec,
+ struct linespec_result *canonical)
+
{
struct linespec_sals lsal;
- lsal.sals = parse_probes (location, NULL, canonical);
+ lsal.sals = parse_probes (locspec, NULL, canonical);
lsal.canonical
- = xstrdup (event_location_to_string (canonical->location.get ()));
+ = xstrdup (location_spec_to_string (canonical->locspec.get ()));
canonical->lsals.push_back (std::move (lsal));
}
static std::vector<symtab_and_line>
-bkpt_probe_decode_location (struct breakpoint *b,
- struct event_location *location,
- struct program_space *search_pspace)
+bkpt_probe_decode_location_spec (struct breakpoint *b,
+ location_spec *locspec,
+ program_space *search_pspace)
{
- std::vector<symtab_and_line> sals = parse_probes (location, search_pspace, NULL);
+ std::vector<symtab_and_line> sals
+ = parse_probes (locspec, search_pspace, NULL);
if (sals.empty ())
error (_("probe not found"));
return sals;
}
-/* The breakpoint_ops structure to be used in tracepoints. */
-
-void
-tracepoint::re_set ()
-{
- breakpoint_re_set_default (this);
-}
-
int
tracepoint::breakpoint_hit (const struct bp_location *bl,
const address_space *aspace, CORE_ADDR bp_addr,
{
if (!static_trace_marker_id.empty ())
{
- gdb_assert (type == bp_static_tracepoint);
+ gdb_assert (type == bp_static_tracepoint
+ || type == bp_static_marker_tracepoint);
uiout->message ("\tmarker id is %pF\n",
string_field ("static-tracepoint-marker-string-id",
}
void
-tracepoint::print_mention ()
+tracepoint::print_mention () const
{
if (current_uiout->is_mi_like_p ())
return;
gdb_printf (_(" %d"), number);
break;
case bp_static_tracepoint:
+ case bp_static_marker_tracepoint:
gdb_printf (_("Static tracepoint"));
gdb_printf (_(" %d"), number);
break;
}
void
-tracepoint::print_recreate (struct ui_file *fp)
+tracepoint::print_recreate (struct ui_file *fp) const
{
if (type == bp_fast_tracepoint)
gdb_printf (fp, "ftrace");
- else if (type == bp_static_tracepoint)
+ else if (type == bp_static_tracepoint
+ || type == bp_static_marker_tracepoint)
gdb_printf (fp, "strace");
else if (type == bp_tracepoint)
gdb_printf (fp, "trace");
internal_error (__FILE__, __LINE__,
_("unhandled tracepoint type %d"), (int) type);
- gdb_printf (fp, " %s", event_location_to_string (location.get ()));
- print_recreate_thread (this, fp);
+ gdb_printf (fp, " %s", location_spec_to_string (locspec.get ()));
+ print_recreate_thread (fp);
if (pass_count)
gdb_printf (fp, " passcount %d\n", pass_count);
}
-std::vector<symtab_and_line>
-tracepoint::decode_location (struct event_location *location,
- struct program_space *search_pspace)
-{
- return decode_location_default (this, location, search_pspace);
-}
-
/* Virtual table for tracepoints on static probes. */
static void
-tracepoint_probe_create_sals_from_location
- (struct event_location *location,
- struct linespec_result *canonical,
- enum bptype type_wanted)
-{
- /* We use the same method for breakpoint on probes. */
- bkpt_probe_create_sals_from_location (location, canonical, type_wanted);
-}
-
-static std::vector<symtab_and_line>
-tracepoint_probe_decode_location (struct breakpoint *b,
- struct event_location *location,
- struct program_space *search_pspace)
+tracepoint_probe_create_sals_from_location_spec
+ (location_spec *locspec,
+ struct linespec_result *canonical)
{
/* We use the same method for breakpoint on probes. */
- return bkpt_probe_decode_location (b, location, search_pspace);
+ bkpt_probe_create_sals_from_location_spec (locspec, canonical);
}
-/* Dprintf breakpoint_ops methods. */
-
-static void
-dprintf_re_set (struct breakpoint *b)
+void
+dprintf_breakpoint::re_set ()
{
- breakpoint_re_set_default (b);
+ breakpoint_re_set_default (this);
/* extra_string should never be non-NULL for dprintf. */
- gdb_assert (b->extra_string != NULL);
+ gdb_assert (extra_string != NULL);
/* 1 - connect to target 1, that can run breakpoint commands.
2 - create a dprintf, which resolves fine.
answers for target_can_run_breakpoint_commands().
Given absence of finer grained resetting, we get to do
it all the time. */
- if (b->extra_string != NULL)
- update_dprintf_command_list (b);
+ if (extra_string != NULL)
+ update_dprintf_command_list (this);
}
-/* Implement the "print_recreate" breakpoint_ops method for dprintf. */
+/* Implement the "print_recreate" method for dprintf. */
-static void
-dprintf_print_recreate (struct breakpoint *tp, struct ui_file *fp)
+void
+dprintf_breakpoint::print_recreate (struct ui_file *fp) const
{
gdb_printf (fp, "dprintf %s,%s",
- event_location_to_string (tp->location.get ()),
- tp->extra_string.get ());
- print_recreate_thread (tp, fp);
+ location_spec_to_string (locspec.get ()),
+ extra_string.get ());
+ print_recreate_thread (fp);
}
-/* Implement the "after_condition_true" breakpoint_ops method for
- dprintf.
+/* Implement the "after_condition_true" method for dprintf.
dprintf's are implemented with regular commands in their command
list, but we run the commands here instead of before presenting the
also makes it so that the commands of multiple dprintfs at the same
address are all handled. */
-static void
-dprintf_after_condition_true (struct bpstat *bs)
+void
+dprintf_breakpoint::after_condition_true (struct bpstat *bs)
{
/* dprintf's never cause a stop. This wasn't set in the
check_status hook instead because that would make the dprintf's
markers (`-m'). */
static void
-strace_marker_create_sals_from_location (struct event_location *location,
- struct linespec_result *canonical,
- enum bptype type_wanted)
+strace_marker_create_sals_from_location_spec (location_spec *locspec,
+ struct linespec_result *canonical)
{
struct linespec_sals lsal;
const char *arg_start, *arg;
- arg = arg_start = get_linespec_location (location)->spec_string;
+ arg = arg_start = as_linespec_location_spec (locspec)->spec_string;
lsal.sals = decode_static_tracepoint_spec (&arg);
std::string str (arg_start, arg - arg_start);
const char *ptr = str.c_str ();
- canonical->location
- = new_linespec_location (&ptr, symbol_name_match_type::FULL);
+ canonical->locspec
+ = new_linespec_location_spec (&ptr, symbol_name_match_type::FULL);
lsal.canonical
- = xstrdup (event_location_to_string (canonical->location.get ()));
+ = xstrdup (location_spec_to_string (canonical->locspec.get ()));
canonical->lsals.push_back (std::move (lsal));
}
enum bpdisp disposition,
int thread,
int task, int ignore_count,
- const struct breakpoint_ops *ops,
int from_tty, int enabled,
int internal, unsigned flags)
{
for (size_t i = 0; i < lsal.sals.size (); i++)
{
- event_location_up location
- = copy_event_location (canonical->location.get ());
-
- std::unique_ptr<tracepoint> tp (new tracepoint ());
- init_breakpoint_sal (tp.get (), gdbarch, lsal.sals[i],
- std::move (location), NULL,
- std::move (cond_string),
- std::move (extra_string),
- type_wanted, disposition,
- thread, task, ignore_count, ops,
- from_tty, enabled, internal, flags,
- canonical->special_display);
+ location_spec_up locspec = canonical->locspec->clone ();
+
+ std::unique_ptr<tracepoint> tp
+ (new tracepoint (gdbarch,
+ type_wanted,
+ lsal.sals[i],
+ std::move (locspec),
+ NULL,
+ std::move (cond_string),
+ std::move (extra_string),
+ disposition,
+ thread, task, ignore_count,
+ from_tty, enabled, flags,
+ canonical->special_display));
+
/* Given that its possible to have multiple markers with
the same string id, if the user is creating a static
tracepoint by marker id ("strace -m MARKER_ID"), then
}
}
-static std::vector<symtab_and_line>
-strace_marker_decode_location (struct breakpoint *b,
- struct event_location *location,
- struct program_space *search_pspace)
+std::vector<symtab_and_line>
+static_marker_tracepoint::decode_location_spec (location_spec *locspec,
+ program_space *search_pspace)
{
- struct tracepoint *tp = (struct tracepoint *) b;
- const char *s = get_linespec_location (location)->spec_string;
+ const char *s = as_linespec_location_spec (locspec)->spec_string;
std::vector<symtab_and_line> sals = decode_static_tracepoint_spec (&s);
- if (sals.size () > tp->static_trace_marker_id_idx)
+ if (sals.size () > static_trace_marker_id_idx)
{
- sals[0] = sals[tp->static_trace_marker_id_idx];
+ sals[0] = sals[static_trace_marker_id_idx];
sals.resize (1);
return sals;
}
else
- error (_("marker %s not found"), tp->static_trace_marker_id.c_str ());
+ error (_("marker %s not found"), static_trace_marker_id.c_str ());
}
-static struct breakpoint_ops strace_marker_breakpoint_ops;
+/* Static tracepoints with marker (`-m'). */
+static struct breakpoint_ops strace_marker_breakpoint_ops =
+{
+ strace_marker_create_sals_from_location_spec,
+ strace_marker_create_breakpoints_sal,
+};
static int
strace_marker_p (struct breakpoint *b)
{
- return b->ops == &strace_marker_breakpoint_ops;
+ return b->type == bp_static_marker_tracepoint;
}
/* Delete a breakpoint and clean up all traces of it in the data
struct symbol *sym;
struct static_tracepoint_marker *tpmarker;
struct ui_out *uiout = current_uiout;
- struct explicit_location explicit_loc;
tpmarker = &markers[0];
b->loc->line_number = sal2.line;
b->loc->symtab = sym != NULL ? sal2.symtab : NULL;
- b->location.reset (NULL);
- initialize_explicit_location (&explicit_loc);
- explicit_loc.source_filename
- = ASTRDUP (symtab_to_filename_for_display (sal2.symtab));
- explicit_loc.line_offset.offset = b->loc->line_number;
- explicit_loc.line_offset.sign = LINE_OFFSET_NONE;
- b->location = new_explicit_location (&explicit_loc);
+ std::unique_ptr<explicit_location_spec> els
+ (new explicit_location_spec ());
+ els->source_filename
+ = xstrdup (symtab_to_filename_for_display (sal2.symtab));
+ els->line_offset.offset = b->loc->line_number;
+ els->line_offset.sign = LINE_OFFSET_NONE;
+
+ b->locspec = std::move (els);
/* Might be nice to check if function changed, and warn if
so. */
untouched. */
void
-update_breakpoint_locations (struct breakpoint *b,
+update_breakpoint_locations (code_breakpoint *b,
struct program_space *filter_pspace,
gdb::array_view<const symtab_and_line> sals,
gdb::array_view<const symtab_and_line> sals_end)
switch_to_program_space_and_thread (sal.pspace);
- new_loc = add_location_to_breakpoint (b, &sal);
+ new_loc = b->add_location (sal);
/* Reparse conditions, they might contain references to the
old symtab. */
gdb::observers::breakpoint_modified.notify (b);
}
-/* Find the SaL locations corresponding to the given LOCATION.
+/* Find the SaL locations corresponding to the given LOCSPEC.
On return, FOUND will be 1 if any SaL was found, zero otherwise. */
static std::vector<symtab_and_line>
-location_to_sals (struct breakpoint *b, struct event_location *location,
- struct program_space *search_pspace, int *found)
+location_spec_to_sals (struct breakpoint *b, location_spec *locspec,
+ struct program_space *search_pspace, int *found)
{
struct gdb_exception exception;
- gdb_assert (b->ops != NULL);
-
std::vector<symtab_and_line> sals;
try
{
- sals = b->ops->decode_location (b, location, search_pspace);
+ sals = b->decode_location_spec (locspec, search_pspace);
}
catch (gdb_exception_error &e)
{
b->condition_not_parsed = 0;
}
- if (b->type == bp_static_tracepoint && !strace_marker_p (b))
+ if (b->type == bp_static_tracepoint)
sals[0] = update_static_tracepoint (b, sals[0]);
*found = 1;
locations. */
static void
-breakpoint_re_set_default (struct breakpoint *b)
+breakpoint_re_set_default (code_breakpoint *b)
{
struct program_space *filter_pspace = current_program_space;
std::vector<symtab_and_line> expanded, expanded_end;
int found;
- std::vector<symtab_and_line> sals = location_to_sals (b, b->location.get (),
- filter_pspace, &found);
+ std::vector<symtab_and_line> sals
+ = location_spec_to_sals (b, b->locspec.get (), filter_pspace, &found);
if (found)
expanded = std::move (sals);
- if (b->location_range_end != NULL)
+ if (b->locspec_range_end != nullptr)
{
std::vector<symtab_and_line> sals_end
- = location_to_sals (b, b->location_range_end.get (),
- filter_pspace, &found);
+ = location_spec_to_sals (b, b->locspec_range_end.get (),
+ filter_pspace, &found);
if (found)
expanded_end = std::move (sals_end);
}
calls parse_breakpoint_sals. Return 1 for success, zero for failure. */
static void
-create_sals_from_location_default (struct event_location *location,
- struct linespec_result *canonical,
- enum bptype type_wanted)
+create_sals_from_location_spec_default (location_spec *locspec,
+ struct linespec_result *canonical)
{
- parse_breakpoint_sals (location, canonical);
-}
-
-/* Call create_breakpoints_sal for the given arguments. This is the default
- function for the `create_breakpoints_sal' method of
- breakpoint_ops. */
-
-static void
-create_breakpoints_sal_default (struct gdbarch *gdbarch,
- struct linespec_result *canonical,
- gdb::unique_xmalloc_ptr<char> cond_string,
- gdb::unique_xmalloc_ptr<char> extra_string,
- enum bptype type_wanted,
- enum bpdisp disposition,
- int thread,
- int task, int ignore_count,
- const struct breakpoint_ops *ops,
- int from_tty, int enabled,
- int internal, unsigned flags)
-{
- create_breakpoints_sal (gdbarch, canonical,
- std::move (cond_string),
- std::move (extra_string),
- type_wanted, disposition,
- thread, task, ignore_count, ops, from_tty,
- enabled, internal, flags);
+ parse_breakpoint_sals (locspec, canonical);
}
/* Decode the line represented by S by calling decode_line_full. This is the
default function for the `decode_location' method of breakpoint_ops. */
static std::vector<symtab_and_line>
-decode_location_default (struct breakpoint *b,
- struct event_location *location,
- struct program_space *search_pspace)
+decode_location_spec_default (struct breakpoint *b,
+ location_spec *locspec,
+ program_space *search_pspace)
{
struct linespec_result canonical;
- decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, search_pspace,
+ decode_line_full (locspec, DECODE_LINE_FUNFIRSTLINE, search_pspace,
NULL, 0, &canonical, multiple_symbols_all,
b->filter.get ());
input_radix = b->input_radix;
set_language (b->language);
- b->ops->re_set (b);
+ b->re_set ();
}
/* Re-set breakpoint locations for the current program space.
if (tp->control.single_step_breakpoints == NULL)
{
+ std::unique_ptr<breakpoint> b
+ (new momentary_breakpoint (gdbarch, bp_single_step,
+ current_program_space,
+ null_frame_id,
+ tp->global_num));
+
tp->control.single_step_breakpoints
- = new_single_step_breakpoint (tp->global_num, gdbarch);
+ = add_to_breakpoint_chain (std::move (b));
}
sal = find_pc_line (pc, 0);
sal.pc = pc;
sal.section = find_pc_overlay (pc);
sal.explicit_pc = 1;
- add_location_to_breakpoint (tp->control.single_step_breakpoints, &sal);
+
+ auto *ss_bp
+ = static_cast<momentary_breakpoint *> (tp->control.single_step_breakpoints);
+ ss_bp->add_location (sal);
update_global_location_list (UGLL_INSERT);
}
static void
trace_command (const char *arg, int from_tty)
{
- event_location_up location = string_to_event_location (&arg,
- current_language);
- const struct breakpoint_ops *ops = breakpoint_ops_for_event_location
- (location.get (), true /* is_tracepoint */);
+ location_spec_up locspec = string_to_location_spec (&arg,
+ current_language);
+ const struct breakpoint_ops *ops = breakpoint_ops_for_location_spec
+ (locspec.get (), true /* is_tracepoint */);
create_breakpoint (get_current_arch (),
- location.get (),
+ locspec.get (),
NULL, 0, arg, false, 1 /* parse arg */,
0 /* tempflag */,
bp_tracepoint /* type_wanted */,
static void
ftrace_command (const char *arg, int from_tty)
{
- event_location_up location = string_to_event_location (&arg,
- current_language);
+ location_spec_up locspec = string_to_location_spec (&arg,
+ current_language);
create_breakpoint (get_current_arch (),
- location.get (),
+ locspec.get (),
NULL, 0, arg, false, 1 /* parse arg */,
0 /* tempflag */,
bp_fast_tracepoint /* type_wanted */,
0 /* Ignore count */,
pending_break_support,
- &vtable_breakpoint_ops,
+ &code_breakpoint_ops,
from_tty,
1 /* enabled */,
0 /* internal */, 0);
static void
strace_command (const char *arg, int from_tty)
{
- struct breakpoint_ops *ops;
- event_location_up location;
+ const struct breakpoint_ops *ops;
+ location_spec_up locspec;
+ enum bptype type;
/* Decide if we are dealing with a static tracepoint marker (`-m'),
or with a normal static tracepoint. */
if (arg && startswith (arg, "-m") && isspace (arg[2]))
{
ops = &strace_marker_breakpoint_ops;
- location = new_linespec_location (&arg, symbol_name_match_type::FULL);
+ locspec = new_linespec_location_spec (&arg,
+ symbol_name_match_type::FULL);
+ type = bp_static_marker_tracepoint;
}
else
{
- ops = &vtable_breakpoint_ops;
- location = string_to_event_location (&arg, current_language);
+ ops = &code_breakpoint_ops;
+ locspec = string_to_location_spec (&arg, current_language);
+ type = bp_static_tracepoint;
}
create_breakpoint (get_current_arch (),
- location.get (),
+ locspec.get (),
NULL, 0, arg, false, 1 /* parse arg */,
0 /* tempflag */,
- bp_static_tracepoint /* type_wanted */,
+ type /* type_wanted */,
0 /* Ignore count */,
pending_break_support,
ops,
"has no source form, ignoring it"),
utp->number);
- event_location_up location = string_to_event_location (&addr_str,
- current_language);
+ location_spec_up locspec = string_to_location_spec (&addr_str,
+ current_language);
if (!create_breakpoint (get_current_arch (),
- location.get (),
+ locspec.get (),
utp->cond_string.get (), -1, addr_str,
false /* force_condition */,
0 /* parse cond/thread */,
utp->type /* type_wanted */,
0 /* Ignore count */,
pending_break_support,
- &vtable_breakpoint_ops,
+ &code_breakpoint_ops,
0 /* from_tty */,
utp->enabled /* enabled */,
0 /* internal */,
}
void
-print_recreate_thread (struct breakpoint *b, struct ui_file *fp)
+breakpoint::print_recreate_thread (struct ui_file *fp) const
{
- if (b->thread != -1)
- gdb_printf (fp, " thread %d", b->thread);
+ if (thread != -1)
+ gdb_printf (fp, " thread %d", thread);
- if (b->task != 0)
- gdb_printf (fp, " task %d", b->task);
+ if (task != 0)
+ gdb_printf (fp, " task %d", task);
gdb_printf (fp, "\n");
}
if (filter && !filter (tp))
continue;
- tp->ops->print_recreate (tp, &fp);
+ tp->print_recreate (&fp);
/* Note, we can't rely on tp->number for anything, as we can't
assume the recreated breakpoint numbers will match. Use $bpnum
/* This help string is used to consolidate all the help string for specifying
locations used by several commands. */
-#define LOCATION_HELP_STRING \
+#define LOCATION_SPEC_HELP_STRING \
"Linespecs are colon-separated lists of location parameters, such as\n\
source filename, function name, label name, and line number.\n\
Example: To specify the start of a label named \"the_top\" in the\n\
\n\
With the \"-force-condition\" flag, the condition is defined even when\n\
it is invalid for all current locations.\n\
-\n" LOCATION_HELP_STRING "\n\n\
+\n" LOCATION_SPEC_HELP_STRING "\n\n\
Multiple breakpoints at one place are permitted, and useful if their\n\
conditions are different.\n\
\n\
loc->symtab = NULL;
}
-void
-initialize_breakpoint_ops (void)
-{
- static int initialized = 0;
-
- struct breakpoint_ops *ops;
-
- if (initialized)
- return;
- initialized = 1;
-
- /* The breakpoint_ops structure to be inherit by all kinds of
- breakpoints (real breakpoints, i.e., user "break" breakpoints,
- internal and momentary breakpoints, etc.). */
- ops = &bkpt_base_breakpoint_ops;
- *ops = vtable_breakpoint_ops;
-
- /* The breakpoint_ops structure to be used in regular breakpoints. */
- ops = &bkpt_breakpoint_ops;
- *ops = bkpt_base_breakpoint_ops;
- ops->resources_needed = bkpt_resources_needed;
- ops->print_it = bkpt_print_it;
- ops->print_mention = bkpt_print_mention;
- ops->print_recreate = bkpt_print_recreate;
-
- /* Ranged breakpoints. */
- ops = &ranged_breakpoint_ops;
- *ops = bkpt_breakpoint_ops;
- ops->breakpoint_hit = breakpoint_hit_ranged_breakpoint;
- ops->resources_needed = resources_needed_ranged_breakpoint;
- ops->print_it = print_it_ranged_breakpoint;
- ops->print_one = print_one_ranged_breakpoint;
- ops->print_one_detail = print_one_detail_ranged_breakpoint;
- ops->print_mention = print_mention_ranged_breakpoint;
- ops->print_recreate = print_recreate_ranged_breakpoint;
-
- /* Probe breakpoints. */
- ops = &bkpt_probe_breakpoint_ops;
- *ops = bkpt_breakpoint_ops;
- ops->insert_location = bkpt_probe_insert_location;
- ops->remove_location = bkpt_probe_remove_location;
- ops->create_sals_from_location = bkpt_probe_create_sals_from_location;
- ops->decode_location = bkpt_probe_decode_location;
-
- /* Probe tracepoints. */
- ops = &tracepoint_probe_breakpoint_ops;
- *ops = vtable_breakpoint_ops;
- ops->create_sals_from_location = tracepoint_probe_create_sals_from_location;
- ops->decode_location = tracepoint_probe_decode_location;
-
- /* Static tracepoints with marker (`-m'). */
- ops = &strace_marker_breakpoint_ops;
- *ops = vtable_breakpoint_ops;
- ops->create_sals_from_location = strace_marker_create_sals_from_location;
- ops->create_breakpoints_sal = strace_marker_create_breakpoints_sal;
- ops->decode_location = strace_marker_decode_location;
-
- ops = &dprintf_breakpoint_ops;
- *ops = bkpt_breakpoint_ops;
- ops->re_set = dprintf_re_set;
- ops->print_recreate = dprintf_print_recreate;
- ops->after_condition_true = dprintf_after_condition_true;
- ops->breakpoint_hit = dprintf_breakpoint_hit;
-}
-
/* Chain containing all defined "enable breakpoint" subcommands. */
static struct cmd_list_element *enablebreaklist = NULL;
{
struct cmd_list_element *c;
- initialize_breakpoint_ops ();
-
gdb::observers::solib_unloaded.attach (disable_breakpoints_in_unloaded_shlib,
"breakpoint");
gdb::observers::free_objfile.attach (disable_breakpoints_in_freed_objfile,
\n\
With no argument, clears all breakpoints in the line that the selected frame\n\
is executing in.\n"
-"\n" LOCATION_HELP_STRING "\n\n\
+"\n" LOCATION_SPEC_HELP_STRING "\n\n\
See also the \"delete\" command which clears breakpoints by number."));
add_com_alias ("cl", clear_cmd, class_breakpoint, 1);
by printing the $_sdata variable like any other convenience variable.\n\
\n\
CONDITION is a boolean expression.\n\
-\n" LOCATION_HELP_STRING "\n\n\
+\n" LOCATION_SPEC_HELP_STRING "\n\n\
Multiple tracepoints at one place are permitted, and useful if their\n\
conditions are different.\n\
\n\
Set a dynamic printf at specified location.\n\
dprintf location,format string,arg1,arg2,...\n\
location may be a linespec, explicit, or address location.\n"
-"\n" LOCATION_HELP_STRING));
+"\n" LOCATION_SPEC_HELP_STRING));
set_cmd_completer (c, location_completer);
add_setshow_enum_cmd ("dprintf-style", class_support,