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);
+ create_sals_from_location_spec_default (location_spec *locspec,
+ linespec_result *canonical);
static void create_breakpoints_sal (struct gdbarch *,
struct linespec_result *,
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,
+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
static void mention (const breakpoint *);
-static struct breakpoint *set_raw_breakpoint_without_location (struct gdbarch *,
- enum bptype);
-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);
+static breakpoint *add_to_breakpoint_chain (std::unique_ptr<breakpoint> &&b);
static struct breakpoint *
momentary_breakpoint_from_master (struct breakpoint *orig,
enum bptype type,
- 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 std::vector<symtab_and_line> bkpt_probe_decode_location
+static std::vector<symtab_and_line> bkpt_probe_decode_location_spec
(struct breakpoint *b,
- struct event_location *location,
+ 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. */
enum ugll_insert_mode
static int strace_marker_p (struct breakpoint *b);
-static void bkpt_probe_create_sals_from_location
- (struct event_location *location,
+static void bkpt_probe_create_sals_from_location_spec
+ (location_spec *locspec,
struct linespec_result *canonical);
-static void tracepoint_probe_create_sals_from_location
- (struct event_location *location,
+static void tracepoint_probe_create_sals_from_location_spec
+ (location_spec *locspec,
struct linespec_result *canonical);
-const struct breakpoint_ops base_breakpoint_ops =
+const struct breakpoint_ops code_breakpoint_ops =
{
- create_sals_from_location_default,
+ create_sals_from_location_spec_default,
create_breakpoints_sal,
};
/* Breakpoints set on probes. */
static const struct breakpoint_ops bkpt_probe_breakpoint_ops =
{
- bkpt_probe_create_sals_from_location,
+ bkpt_probe_create_sals_from_location_spec,
create_breakpoints_sal,
};
/* Tracepoints set on probes. */
static const struct breakpoint_ops tracepoint_probe_breakpoint_ops =
{
- tracepoint_probe_create_sals_from_location,
+ tracepoint_probe_create_sals_from_location_spec,
create_breakpoints_sal,
};
+/* 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 base_breakpoint::base_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_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
{
- using base_breakpoint::base_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;
void print_mention () const override;
};
-/* Momentary breakpoints. */
-struct momentary_breakpoint : public base_breakpoint
-{
- using base_breakpoint::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;
/* Ranged breakpoints. */
struct ranged_breakpoint : public ordinary_breakpoint
{
- explicit ranged_breakpoint (struct gdbarch *gdbarch)
+ 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,
{
using tracepoint::tracepoint;
- std::vector<symtab_and_line> decode_location
- (struct event_location *location,
+ std::vector<symtab_and_line> decode_location_spec
+ (struct location_spec *locspec,
struct program_space *search_pspace) override;
};
/* Factory function to create an appropriate instance of breakpoint given
TYPE. */
-static std::unique_ptr<breakpoint>
-new_breakpoint_from_type (struct gdbarch *gdbarch, 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 (gdbarch, type);
+ 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 (gdbarch, type);
+ b = new tracepoint (gdbarch, type,
+ std::forward<Arg> (args)...);
break;
case bp_static_marker_tracepoint:
- b = new static_marker_tracepoint (gdbarch, type);
+ b = new static_marker_tracepoint (gdbarch, type,
+ std::forward<Arg> (args)...);
break;
case bp_dprintf:
- b = new dprintf_breakpoint (gdbarch, type);
- 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 (gdbarch, type);
- break;
-
- case bp_longjmp:
- case bp_exception:
- b = new longjmp_breakpoint (gdbarch, type);
- 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 (gdbarch, type);
+ 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
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 = b->allocate_location ();
+ 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:
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)
{
create_internal_breakpoint (struct gdbarch *gdbarch,
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);
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);
- initialize_explicit_location (&explicit_loc);
- explicit_loc.function_name = ASTRDUP (func_name);
- b->location = new_explicit_location (&explicit_loc);
+ 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);
- b->location = new_probe_location ("-probe-stap libc:longjmp");
+ 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);
- initialize_explicit_location (&explicit_loc);
- explicit_loc.function_name = ASTRDUP (func_name);
- b->location = new_explicit_location (&explicit_loc);
+ 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);
- initialize_explicit_location (&explicit_loc);
- explicit_loc.function_name = ASTRDUP (func_name);
- b->location = new_explicit_location (&explicit_loc);
+ 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);
- b->location = new_probe_location ("-probe-stap libgcc:unwind");
+ 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 = gdbarch_convert_from_func_ptr_addr
(gdbarch, addr, current_inferior ()->top_target ());
b = create_internal_breakpoint (gdbarch, addr, bp_exception_master);
- initialize_explicit_location (&explicit_loc);
- explicit_loc.function_name = ASTRDUP (func_name);
- b->location = new_explicit_location (&explicit_loc);
+ 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)
{
/* 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;
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;
}
}
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. */
/* 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]);
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:
return result;
}
-/* 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)
-{
- std::unique_ptr<breakpoint> b = new_breakpoint_from_type (gdbarch, bptype);
-
- 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 symtab_and_line sal,
- enum bptype bptype)
-{
- 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)
-{
- std::unique_ptr<breakpoint> b = new_breakpoint_from_type (gdbarch, bptype);
-
- init_raw_breakpoint (b.get (), sal, bptype);
- 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, 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,
- 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, 1);
+ momentary_breakpoint_from_master (b, bp_std_terminate, 1,
+ inferior_thread ()->global_num);
}
}
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);
/* See breakpoint.h. */
-catchpoint::catchpoint (struct gdbarch *gdbarch, bool temp,
- const char *cond_string_)
- : base_breakpoint (gdbarch, bp_catchpoint)
+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 (this, sal, bp_catchpoint);
+/* See breakpoint.h. */
+
+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);
- if (cond_string_ != nullptr)
- cond_string = make_unique_xstrdup (cond_string_);
- disposition = temp ? disp_del : disp_donttouch;
+ pspace = current_program_space;
}
void
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 (gdbarch,
- bp_single_step));
-
- 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);
- 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,
- int loc_enabled)
+ int loc_enabled,
+ int thread)
{
- struct breakpoint *copy;
-
- copy = set_raw_breakpoint_without_location (orig->gdbarch, type);
+ 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->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;
- return momentary_breakpoint_from_master (orig, orig->type, 0);
+ return momentary_breakpoint_from_master (orig, orig->type, 0,
+ orig->thread);
}
breakpoint_up
}
}
-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_location(), that mostly uninitialized
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 = b->allocate_location ();
- 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, sal, type);
- 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
- || type == bp_static_marker_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 (gdbarch, 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 &base_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 &base_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 &base_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);
+ 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 (gdbarch,
type_wanted);
- b->location = copy_event_location (location);
+ 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,
- &base_breakpoint_ops,
+ &code_breakpoint_ops,
from_tty,
1 /* enabled */,
0 /* internal */,
ranged_breakpoint::print_recreate (struct ui_file *fp) const
{
gdb_printf (fp, "break-range %s, %s",
- event_location_to_string (location.get ()),
- event_location_to_string (location_range_end.get ()));
+ location_spec_to_string (locspec.get ()),
+ location_spec_to_string (locspec_range_end.get ()));
print_recreate_thread (fp);
}
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. */
- std::unique_ptr<breakpoint> br (new ranged_breakpoint (get_current_arch ()));
- init_raw_breakpoint (br.get (), sal_start, bp_hardware_breakpoint);
- b = add_to_breakpoint_chain (std::move (br));
+ /* Now set up the breakpoint and install it. */
- 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;
+ std::unique_ptr<breakpoint> br
+ (new ranged_breakpoint (get_current_arch (),
+ sal_start, length,
+ std::move (start_locspec),
+ std::move (end_locspec)));
- mention (b);
- gdb::observers::breakpoint_created.notify (b);
- update_global_location_list (UGLL_MAY_INSERT);
+ install_breakpoint (false, std::move (br), true);
}
/* Return non-zero if EXP is verified as constant. Returned zero
/* 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,
- 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, sal, bp_catchpoint);
-
- 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. */
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)
}
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 ();
}
/* 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;
}
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)
}
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)
internal_error (__FILE__, __LINE__,
_("unhandled breakpoint type %d"), (int) type);
- gdb_printf (fp, " %s", event_location_to_string (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. */
}
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)
{
- if (event_location_type (location) == PROBE_LOCATION)
- return bkpt_probe_decode_location (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_default (this, location, search_pspace);
+ return decode_location_spec_default (this, locspec, search_pspace);
}
/* Virtual table for internal breakpoints. */
}
static void
-bkpt_probe_create_sals_from_location (struct event_location *location,
- struct linespec_result *canonical)
+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,
internal_error (__FILE__, __LINE__,
_("unhandled tracepoint type %d"), (int) type);
- gdb_printf (fp, " %s", event_location_to_string (location.get ()));
+ 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)
-{
- if (event_location_type (location) == PROBE_LOCATION)
- return bkpt_probe_decode_location (this, location, 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,
+tracepoint_probe_create_sals_from_location_spec
+ (location_spec *locspec,
struct linespec_result *canonical)
{
/* We use the same method for breakpoint on probes. */
- bkpt_probe_create_sals_from_location (location, canonical);
+ bkpt_probe_create_sals_from_location_spec (locspec, canonical);
}
void
dprintf_breakpoint::print_recreate (struct ui_file *fp) const
{
gdb_printf (fp, "dprintf %s,%s",
- event_location_to_string (location.get ()),
+ location_spec_to_string (locspec.get ()),
extra_string.get ());
print_recreate_thread (fp);
}
markers (`-m'). */
static void
-strace_marker_create_sals_from_location (struct event_location *location,
- struct linespec_result *canonical)
+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 (gdbarch,
- type_wanted));
- 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
}
std::vector<symtab_and_line>
-static_marker_tracepoint::decode_location (struct event_location *location,
- struct program_space *search_pspace)
+static_marker_tracepoint::decode_location_spec (location_spec *locspec,
+ program_space *search_pspace)
{
- 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 () > static_trace_marker_id_idx)
/* Static tracepoints with marker (`-m'). */
static struct breakpoint_ops strace_marker_breakpoint_ops =
{
- strace_marker_create_sals_from_location,
+ strace_marker_create_sals_from_location_spec,
strace_marker_create_breakpoints_sal,
};
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;
try
{
- sals = b->decode_location (location, search_pspace);
+ sals = b->decode_location_spec (locspec, search_pspace);
}
catch (gdb_exception_error &e)
{
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)
+create_sals_from_location_spec_default (location_spec *locspec,
+ struct linespec_result *canonical)
{
- parse_breakpoint_sals (location, canonical);
+ 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 ());
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,
- &base_breakpoint_ops,
+ &code_breakpoint_ops,
from_tty,
1 /* enabled */,
0 /* internal */, 0);
strace_command (const char *arg, int from_tty)
{
const struct breakpoint_ops *ops;
- event_location_up location;
+ location_spec_up locspec;
enum bptype type;
/* Decide if we are dealing with a static tracepoint marker (`-m'),
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 = &base_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 */,
type /* type_wanted */,
"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,
- &base_breakpoint_ops,
+ &code_breakpoint_ops,
0 /* from_tty */,
utp->enabled /* enabled */,
0 /* internal */,
/* 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\
\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,