static struct breakpoint *set_raw_breakpoint_without_location (struct gdbarch *,
enum bptype,
- struct breakpoint_ops *);
+ const struct breakpoint_ops *);
/* This function is used in gdbtk sources and thus can not be made
static. */
struct breakpoint *set_raw_breakpoint (struct gdbarch *gdbarch,
struct symtab_and_line,
- enum bptype, struct breakpoint_ops *);
+ enum bptype,
+ const struct breakpoint_ops *);
static struct breakpoint *
momentary_breakpoint_from_master (struct breakpoint *orig,
enum bptype type,
- struct breakpoint_ops *ops);
+ const struct breakpoint_ops *ops);
static void breakpoint_adjustment_warning (CORE_ADDR, CORE_ADDR, int, int);
static int is_hardware_watchpoint (const struct breakpoint *bpt);
-static int is_watchpoint (const struct breakpoint *bpt);
-
static void insert_breakpoint_locations (void);
static int syscall_catchpoint_p (struct breakpoint *b);
#define is_marker_spec(s) \
(s != NULL && strncmp (s, "-m", 2) == 0 && ((s)[2] == ' ' || (s)[2] == '\t'))
-/* Forward declarations. */
+/* The abstract base class all breakpoint_ops structures inherit
+ from. */
+static struct breakpoint_ops base_breakpoint_ops;
+
+/* 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;
+
+/* Internal breakpoints class type. */
static struct breakpoint_ops internal_breakpoint_ops;
+
+/* Momentary breakpoints class type. */
static struct breakpoint_ops momentary_breakpoint_ops;
+/* The breakpoint_ops structure to be used in regular user created
+ breakpoints. */
+struct breakpoint_ops bkpt_breakpoint_ops;
+
/* A reference-counted struct command_line. This lets multiple
breakpoints share a single command list. */
struct counted_command_line
set_breakpoint_condition (struct breakpoint *b, char *exp,
int from_tty)
{
- struct bp_location *loc = b->loc;
+ xfree (b->cond_string);
+ b->cond_string = NULL;
- for (; loc; loc = loc->next)
+ if (is_watchpoint (b))
{
- xfree (loc->cond);
- loc->cond = NULL;
+ struct watchpoint *w = (struct watchpoint *) b;
+
+ xfree (w->cond_exp);
+ w->cond_exp = NULL;
+ }
+ else
+ {
+ struct bp_location *loc;
+
+ for (loc = b->loc; loc; loc = loc->next)
+ {
+ xfree (loc->cond);
+ loc->cond = NULL;
+ }
}
- xfree (b->cond_string);
- b->cond_string = NULL;
- xfree (b->cond_exp);
- b->cond_exp = NULL;
if (*exp == 0)
{
if (is_watchpoint (b))
{
+ struct watchpoint *w = (struct watchpoint *) b;
+
innermost_block = NULL;
arg = exp;
- b->cond_exp = parse_exp_1 (&arg, 0, 0);
+ w->cond_exp = parse_exp_1 (&arg, 0, 0);
if (*arg)
error (_("Junk at end of expression"));
- b->cond_exp_valid_block = innermost_block;
+ w->cond_exp_valid_block = innermost_block;
}
else
{
+ struct bp_location *loc;
+
for (loc = b->loc; loc; loc = loc->next)
{
arg = exp;
/* Encapsulate tests for different types of tracepoints. */
+static int
+is_tracepoint_type (enum bptype type)
+{
+ return (type == bp_tracepoint
+ || type == bp_fast_tracepoint
+ || type == bp_static_tracepoint);
+}
+
int
is_tracepoint (const struct breakpoint *b)
{
- return (b->type == bp_tracepoint
- || b->type == bp_fast_tracepoint
- || b->type == bp_static_tracepoint);
+ return is_tracepoint_type (b->type);
}
-
+
/* A helper function that validates that COMMANDS are valid for a
breakpoint. This function will throw an exception if a problem is
found. */
/* Return true if BPT is of any watchpoint kind, hardware or
software. */
-static int
+int
is_watchpoint (const struct breakpoint *bpt)
{
return (is_hardware_watchpoint (bpt)
|| bpt->type == bp_watchpoint);
}
-/* Assuming that B is a watchpoint: returns true if the current thread
- and its running state are safe to evaluate or update watchpoint B.
- Watchpoints on local expressions need to be evaluated in the
- context of the thread that was current when the watchpoint was
- created, and, that thread needs to be stopped to be able to select
- the correct frame context. Watchpoints on global expressions can
- be evaluated on any thread, and in any state. It is presently left
- to the target allowing memory accesses when threads are
- running. */
+/* Returns true if the current thread and its running state are safe
+ to evaluate or update watchpoint B. Watchpoints on local
+ expressions need to be evaluated in the context of the thread that
+ was current when the watchpoint was created, and, that thread needs
+ to be stopped to be able to select the correct frame context.
+ Watchpoints on global expressions can be evaluated on any thread,
+ and in any state. It is presently left to the target allowing
+ memory accesses when threads are running. */
static int
-watchpoint_in_thread_scope (struct breakpoint *b)
+watchpoint_in_thread_scope (struct watchpoint *b)
{
return (ptid_equal (b->watchpoint_thread, null_ptid)
|| (ptid_equal (inferior_ptid, b->watchpoint_thread)
associated bp_watchpoint_scope breakpoint. */
static void
-watchpoint_del_at_next_stop (struct breakpoint *b)
+watchpoint_del_at_next_stop (struct watchpoint *w)
{
- gdb_assert (is_watchpoint (b));
+ struct breakpoint *b = &w->base;
if (b->related_breakpoint != b)
{
watchpoint removal from inferior. */
static void
-update_watchpoint (struct breakpoint *b, int reparse)
+update_watchpoint (struct watchpoint *b, int reparse)
{
int within_current_scope;
struct frame_id saved_frame_id;
int frame_saved;
- gdb_assert (is_watchpoint (b));
-
/* If this is a local watchpoint, we only want to check if the
watchpoint frame is in scope if the current thread is the thread
that was used to create the watchpoint. */
if (!watchpoint_in_thread_scope (b))
return;
- if (b->disposition == disp_del_at_next_stop)
+ if (b->base.disposition == disp_del_at_next_stop)
return;
frame_saved = 0;
/* We don't free locations. They are stored in the bp_location array
and update_global_location_list will eventually delete them and
remove breakpoints if needed. */
- b->loc = NULL;
+ b->base.loc = NULL;
if (within_current_scope && reparse)
{
/* Note that unlike with breakpoints, the watchpoint's condition
expression is stored in the breakpoint object, not in the
locations (re)created below. */
- if (b->cond_string != NULL)
+ if (b->base.cond_string != NULL)
{
if (b->cond_exp != NULL)
{
b->cond_exp = NULL;
}
- s = b->cond_string;
+ s = b->base.cond_string;
b->cond_exp = parse_exp_1 (&s, b->cond_exp_valid_block, 0);
}
}
happens, the code that reports it updates b->val directly.
We don't keep track of the memory value for masked
watchpoints. */
- if (!b->val_valid && !is_masked_watchpoint (b))
+ if (!b->val_valid && !is_masked_watchpoint (&b->base))
{
b->val = v;
b->val_valid = 1;
addr = value_address (v);
len = TYPE_LENGTH (value_type (v));
type = hw_write;
- if (b->type == bp_read_watchpoint)
+ if (b->base.type == bp_read_watchpoint)
type = hw_read;
- else if (b->type == bp_access_watchpoint)
+ else if (b->base.type == bp_access_watchpoint)
type = hw_access;
-
- loc = allocate_bp_location (b);
- for (tmp = &(b->loc); *tmp != NULL; tmp = &((*tmp)->next))
+
+ loc = allocate_bp_location (&b->base);
+ for (tmp = &(b->base.loc); *tmp != NULL; tmp = &((*tmp)->next))
;
*tmp = loc;
loc->gdbarch = get_type_arch (value_type (v));
hw_watchpoint_used_count call below counts this
watchpoint, make sure that it is marked as a hardware
watchpoint. */
- if (b->type == bp_watchpoint)
- b->type = bp_hardware_watchpoint;
+ if (b->base.type == bp_watchpoint)
+ b->base.type = bp_hardware_watchpoint;
- i = hw_watchpoint_used_count (b->type, &other_type_used);
+ i = hw_watchpoint_used_count (b->base.type, &other_type_used);
target_resources_ok = target_can_use_hardware_watchpoint
- (b->type, i, other_type_used);
+ (b->base.type, i, other_type_used);
if (target_resources_ok <= 0)
{
- int sw_mode = b->ops->works_in_software_mode (b);
+ int sw_mode = b->base.ops->works_in_software_mode (&b->base);
if (target_resources_ok == 0 && !sw_mode)
error (_("Target does not support this type of "
error (_("There are not enough available hardware "
"resources for this watchpoint."));
else
- b->type = bp_watchpoint;
+ b->base.type = bp_watchpoint;
}
}
- else if (!b->ops->works_in_software_mode (b))
+ else if (!b->base.ops->works_in_software_mode (&b->base))
error (_("Expression cannot be implemented with "
"read/access watchpoint."));
else
- b->type = bp_watchpoint;
+ b->base.type = bp_watchpoint;
- loc_type = (b->type == bp_watchpoint? bp_loc_other
+ loc_type = (b->base.type == bp_watchpoint? bp_loc_other
: bp_loc_hardware_watchpoint);
- for (bl = b->loc; bl; bl = bl->next)
+ for (bl = b->base.loc; bl; bl = bl->next)
bl->loc_type = loc_type;
}
above left it without any location set up. But,
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)
+ if (b->base.type == bp_watchpoint && b->base.loc == NULL)
{
- b->loc = allocate_bp_location (b);
- b->loc->pspace = frame_pspace;
- b->loc->address = -1;
- b->loc->length = -1;
- b->loc->watchpoint_type = -1;
+ struct breakpoint *base = &b->base;
+ base->loc = allocate_bp_location (base);
+ base->loc->pspace = frame_pspace;
+ base->loc->address = -1;
+ base->loc->length = -1;
+ base->loc->watchpoint_type = -1;
}
}
else if (!within_current_scope)
printf_filtered (_("\
Watchpoint %d deleted because the program has left the block\n\
in which its expression is valid.\n"),
- b->number);
+ b->base.number);
watchpoint_del_at_next_stop (b);
}
return 1;
}
+/* Same as should_be_inserted but does the check assuming
+ that the location is not duplicated. */
+
+static int
+unduplicated_should_be_inserted (struct bp_location *bl)
+{
+ int result;
+ const int save_duplicate = bl->duplicate;
+
+ bl->duplicate = 0;
+ result = should_be_inserted (bl);
+ bl->duplicate = save_duplicate;
+ return result;
+}
+
/* Insert a low-level "breakpoint" of some type. BL is the breakpoint
location. Any error messages are printed to TMP_ERROR_STREAM; and
DISABLED_BREAKS, and HW_BREAKPOINT_ERROR are used to report problems.
+ Returns 0 for success, 1 if the bp_location type is not supported or
+ -1 for failure.
NOTE drow/2003-09-09: This routine could be broken down to an
object-style method for each breakpoint or catchpoint type. */
ALL_BREAKPOINTS (bpt)
if (is_hardware_watchpoint (bpt))
- update_watchpoint (bpt, 0 /* don't reparse. */);
+ {
+ struct watchpoint *w = (struct watchpoint *) bpt;
+
+ update_watchpoint (w, 0 /* don't reparse. */);
+ }
update_global_location_list (1);
insert_breakpoint_locations ();
}
-/* insert_breakpoints is used when starting or continuing the program.
- remove_breakpoints is used when the program stops.
- Both return zero if successful,
- or an `errno' value if could not write the inferior. */
+/* Used when starting or continuing the program. */
static void
insert_breakpoint_locations (void)
do_cleanups (cleanups);
}
+/* Used when the program stops.
+ Returns zero if successful, or non-zero if there was a problem
+ removing a breakpoint location. */
+
int
remove_breakpoints (void)
{
static struct breakpoint *
create_internal_breakpoint (struct gdbarch *gdbarch,
CORE_ADDR address, enum bptype type,
- struct breakpoint_ops *ops)
+ const struct breakpoint_ops *ops)
{
struct symtab_and_line sal;
struct breakpoint *b;
case bp_hardware_watchpoint:
case bp_read_watchpoint:
case bp_access_watchpoint:
+ {
+ struct watchpoint *w = (struct watchpoint *) b;
- /* Likewise for watchpoints on local expressions. */
- if (b->exp_valid_block != NULL)
- delete_breakpoint (b);
- else if (context == inf_starting)
- {
- /* Reset val field to force reread of starting value in
- insert_breakpoints. */
- if (b->val)
- value_free (b->val);
- b->val = NULL;
- b->val_valid = 0;
+ /* Likewise for watchpoints on local expressions. */
+ if (w->exp_valid_block != NULL)
+ delete_breakpoint (b);
+ else if (context == inf_starting)
+ {
+ /* Reset val field to force reread of starting value in
+ insert_breakpoints. */
+ if (w->val)
+ value_free (w->val);
+ w->val = NULL;
+ w->val_valid = 0;
}
+ }
break;
default:
break;
as not triggered. */
ALL_BREAKPOINTS (b)
if (is_hardware_watchpoint (b))
- b->watchpoint_triggered = watch_triggered_no;
+ {
+ struct watchpoint *w = (struct watchpoint *) b;
+
+ w->watchpoint_triggered = watch_triggered_no;
+ }
return 0;
}
Mark all watchpoints as unknown. */
ALL_BREAKPOINTS (b)
if (is_hardware_watchpoint (b))
- b->watchpoint_triggered = watch_triggered_unknown;
+ {
+ struct watchpoint *w = (struct watchpoint *) b;
+
+ w->watchpoint_triggered = watch_triggered_unknown;
+ }
return stopped_by_watchpoint;
}
ALL_BREAKPOINTS (b)
if (is_hardware_watchpoint (b))
{
+ struct watchpoint *w = (struct watchpoint *) b;
struct bp_location *loc;
- b->watchpoint_triggered = watch_triggered_no;
+ w->watchpoint_triggered = watch_triggered_no;
for (loc = b->loc; loc; loc = loc->next)
{
- if (is_masked_watchpoint (loc->owner))
+ if (is_masked_watchpoint (b))
{
- CORE_ADDR newaddr = addr & loc->owner->hw_wp_mask;
- CORE_ADDR start = loc->address & loc->owner->hw_wp_mask;
+ CORE_ADDR newaddr = addr & w->hw_wp_mask;
+ CORE_ADDR start = loc->address & w->hw_wp_mask;
if (newaddr == start)
{
- b->watchpoint_triggered = watch_triggered_yes;
+ w->watchpoint_triggered = watch_triggered_yes;
break;
}
}
addr, loc->address,
loc->length))
{
- b->watchpoint_triggered = watch_triggered_yes;
+ w->watchpoint_triggered = watch_triggered_yes;
break;
}
}
watchpoint_check (void *p)
{
bpstat bs = (bpstat) p;
- struct breakpoint *b;
+ struct watchpoint *b;
struct frame_info *fr;
int within_current_scope;
/* BS is built from an existing struct breakpoint. */
gdb_assert (bs->breakpoint_at != NULL);
- b = bs->breakpoint_at;
-
- gdb_assert (is_watchpoint (b));
+ b = (struct watchpoint *) bs->breakpoint_at;
/* If this is a local watchpoint, we only want to check if the
watchpoint frame is in scope if the current thread is the thread
struct value *mark;
struct value *new_val;
- if (is_masked_watchpoint (b))
+ if (is_masked_watchpoint (&b->base))
/* Since we don't know the exact trigger address (from
stopped_data_address), just tell the user we've triggered
a mask watchpoint. */
}
else
{
+ struct ui_out *uiout = current_uiout;
+
/* This seems like the only logical thing to do because
if we temporarily ignored the watchpoint, then when
we reenter the block in which it is valid it contains
ui_out_field_string
(uiout, "reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_SCOPE));
ui_out_text (uiout, "\nWatchpoint ");
- ui_out_field_int (uiout, "wpnum", b->number);
+ ui_out_field_int (uiout, "wpnum", b->base.number);
ui_out_text (uiout,
" deleted because the program has left the block in\n\
which its expression is valid.\n");
/* Make sure the watchpoint's commands aren't executed. */
- decref_counted_command_line (&b->commands);
+ decref_counted_command_line (&b->base.commands);
watchpoint_del_at_next_stop (b);
return WP_DELETED;
return b->ops->breakpoint_hit (bl, aspace, bp_addr);
}
-/* If BS refers to a watchpoint, determine if the watched values
- has actually changed, and we should stop. If not, set BS->stop
- to 0. */
+/* Determine if the watched values have actually changed, and we
+ should stop. If not, set BS->stop to 0. */
+
static void
bpstat_check_watchpoint (bpstat bs)
{
const struct bp_location *bl;
- struct breakpoint *b;
+ struct watchpoint *b;
/* BS is built for existing struct breakpoint. */
bl = bs->bp_location_at;
gdb_assert (bl != NULL);
- b = bs->breakpoint_at;
+ b = (struct watchpoint *) bs->breakpoint_at;
gdb_assert (b != NULL);
- if (is_watchpoint (b))
{
int must_check_value = 0;
- if (b->type == bp_watchpoint)
+ if (b->base.type == bp_watchpoint)
/* For a software watchpoint, we must always check the
watched value. */
must_check_value = 1;
this watchpoint. */
must_check_value = 1;
else if (b->watchpoint_triggered == watch_triggered_unknown
- && b->type == bp_hardware_watchpoint)
+ && b->base.type == bp_hardware_watchpoint)
/* We were stopped by a hardware watchpoint, but the target could
not report the data address. We must check the watchpoint's
value. Access and read watchpoints are out of luck; without
a data address, we can't figure it out. */
must_check_value = 1;
-
+
if (must_check_value)
{
char *message
= xstrprintf ("Error evaluating expression for watchpoint %d\n",
- b->number);
+ b->base.number);
struct cleanup *cleanups = make_cleanup (xfree, message);
int e = catch_errors (watchpoint_check, bs, message,
RETURN_MASK_ALL);
bs->stop = 0;
break;
case WP_VALUE_CHANGED:
- if (b->type == bp_read_watchpoint)
+ if (b->base.type == bp_read_watchpoint)
{
/* There are two cases to consider here:
struct breakpoint *other_b;
ALL_BREAKPOINTS (other_b)
- if ((other_b->type == bp_hardware_watchpoint
- || other_b->type == bp_access_watchpoint)
- && (other_b->watchpoint_triggered
- == watch_triggered_yes))
+ if (other_b->type == bp_hardware_watchpoint
+ || other_b->type == bp_access_watchpoint)
{
- other_write_watchpoint = 1;
- break;
+ struct watchpoint *other_w =
+ (struct watchpoint *) other_b;
+
+ if (other_w->watchpoint_triggered
+ == watch_triggered_yes)
+ {
+ other_write_watchpoint = 1;
+ break;
+ }
}
}
}
break;
case WP_VALUE_NOT_CHANGED:
- if (b->type == bp_hardware_watchpoint
- || b->type == bp_watchpoint)
+ if (b->base.type == bp_hardware_watchpoint
+ || b->base.type == bp_watchpoint)
{
/* Don't stop: write watchpoints shouldn't fire if
the value hasn't changed. */
/* Can't happen. */
case 0:
/* Error from catch_errors. */
- printf_filtered (_("Watchpoint %d deleted.\n"), b->number);
+ printf_filtered (_("Watchpoint %d deleted.\n"), b->base.number);
watchpoint_del_at_next_stop (b);
/* We've already printed what needs to be printed. */
bs->print_it = print_it_done;
bs->stop = gdbpy_should_stop (b->py_bp_object);
if (is_watchpoint (b))
- cond = b->cond_exp;
+ {
+ struct watchpoint *w = (struct watchpoint *) b;
+
+ cond = w->cond_exp;
+ }
else
cond = bl->cond;
if (cond && b->disposition != disp_del_at_next_stop)
{
int within_current_scope = 1;
+ struct watchpoint * w;
/* We use value_mark and value_free_to_mark because it could
be a long time before we return to the command level and
function call. */
struct value *mark = value_mark ();
+ if (is_watchpoint (b))
+ w = (struct watchpoint *) b;
+ else
+ w = NULL;
+
/* Need to select the frame, with all that implies so that
the conditions will have the right context. Because we
use the frame, we will not see an inlined function's
variables when we arrive at a breakpoint at the start
of the inlined function; the current frame will be the
call site. */
- if (!is_watchpoint (b) || b->cond_exp_valid_block == NULL)
+ if (w == NULL || w->cond_exp_valid_block == NULL)
select_frame (get_current_frame ());
else
{
the innermost frame that's executing where it makes
sense to evaluate the condition. It seems
intuitive. */
- frame = block_innermost_frame (b->cond_exp_valid_block);
+ frame = block_innermost_frame (w->cond_exp_valid_block);
if (frame != NULL)
select_frame (frame);
else
out-of-scope event. We'll get to the watchpoint next
iteration. */
if (b->type == bp_watchpoint_scope && b->related_breakpoint != b)
- b->related_breakpoint->watchpoint_triggered = watch_triggered_yes;
+ {
+ struct watchpoint *w = (struct watchpoint *) b->related_breakpoint;
+
+ w->watchpoint_triggered = watch_triggered_yes;
+ }
}
}
&& bs->breakpoint_at
&& is_hardware_watchpoint (bs->breakpoint_at))
{
- update_watchpoint (bs->breakpoint_at, 0 /* don't reparse. */);
+ struct watchpoint *w = (struct watchpoint *) bs->breakpoint_at;
+
+ update_watchpoint (w, 0 /* don't reparse. */);
need_remove_insert = 1;
}
print_breakpoint_location (struct breakpoint *b,
struct bp_location *loc)
{
+ struct ui_out *uiout = current_uiout;
struct cleanup *old_chain = save_current_program_space ();
if (loc != NULL && loc->shlib_disabled)
struct command_line *l;
static char bpenables[] = "nynny";
+ struct ui_out *uiout = current_uiout;
int header_of_multiple = 0;
int part_of_multiple = (loc != NULL);
struct value_print_options opts;
case bp_hardware_watchpoint:
case bp_read_watchpoint:
case bp_access_watchpoint:
- /* Field 4, the address, is omitted (which makes the columns
- not line up too nicely with the headers, but the effect
- is relatively readable). */
- if (opts.addressprint)
- ui_out_field_skip (uiout, "addr");
- annotate_field (5);
- ui_out_field_string (uiout, "what", b->exp_string);
+ {
+ struct watchpoint *w = (struct watchpoint *) b;
+
+ /* Field 4, the address, is omitted (which makes the columns
+ not line up too nicely with the headers, but the effect
+ is relatively readable). */
+ if (opts.addressprint)
+ ui_out_field_skip (uiout, "addr");
+ annotate_field (5);
+ ui_out_field_string (uiout, "what", w->exp_string);
+ }
break;
case bp_breakpoint:
do_cleanups (script_chain);
}
- if (!part_of_multiple && b->pass_count)
+ if (is_tracepoint (b))
{
- annotate_field (10);
- ui_out_text (uiout, "\tpass count ");
- ui_out_field_int (uiout, "pass", b->pass_count);
- ui_out_text (uiout, " \n");
+ struct tracepoint *t = (struct tracepoint *) b;
+
+ if (!part_of_multiple && t->pass_count)
+ {
+ annotate_field (10);
+ ui_out_text (uiout, "\tpass count ");
+ ui_out_field_int (uiout, "pass", t->pass_count);
+ ui_out_text (uiout, " \n");
+ }
}
if (ui_out_is_mi_like_p (uiout) && !part_of_multiple)
{
- if (b->addr_string)
+ if (is_watchpoint (b))
+ {
+ struct watchpoint *w = (struct watchpoint *) b;
+
+ ui_out_field_string (uiout, "original-location", w->exp_string);
+ }
+ else if (b->addr_string)
ui_out_field_string (uiout, "original-location", b->addr_string);
- else if (b->exp_string)
- ui_out_field_string (uiout, "original-location", b->exp_string);
}
}
int allflag)
{
struct cleanup *bkpt_chain;
+ struct ui_out *uiout = current_uiout;
bkpt_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "bkpt");
struct value_print_options opts;
int print_address_bits = 0;
int print_type_col_width = 14;
+ struct ui_out *uiout = current_uiout;
get_user_print_options (&opts);
static void
default_collect_info (void)
{
+ struct ui_out *uiout = current_uiout;
+
/* If it has no value (which is frequently the case), say nothing; a
message like "No default-collect." gets in user's face when it's
not wanted. */
watchpoints_info (char *args, int from_tty)
{
int num_printed = breakpoint_1 (args, 0, is_watchpoint);
+ struct ui_out *uiout = current_uiout;
if (num_printed == 0)
{
watchpoint_locations_match (struct bp_location *loc1,
struct bp_location *loc2)
{
- /* Both of them must not be in moribund_locations. */
- gdb_assert (loc1->owner != NULL);
- gdb_assert (loc2->owner != NULL);
+ struct watchpoint *w1 = (struct watchpoint *) loc1->owner;
+ struct watchpoint *w2 = (struct watchpoint *) loc2->owner;
+
+ /* Both of them must exist. */
+ gdb_assert (w1 != NULL);
+ gdb_assert (w2 != NULL);
/* If the target can evaluate the condition expression in hardware,
then we we need to insert both watchpoints even if they are at
the condition of whichever watchpoint was inserted evaluates to
true, not giving a chance for GDB to check the condition of the
other watchpoint. */
- if ((loc1->owner->cond_exp
+ if ((w1->cond_exp
&& target_can_accel_watchpoint_condition (loc1->address,
loc1->length,
loc1->watchpoint_type,
- loc1->owner->cond_exp))
- || (loc2->owner->cond_exp
+ w1->cond_exp))
+ || (w2->cond_exp
&& target_can_accel_watchpoint_condition (loc2->address,
loc2->length,
loc2->watchpoint_type,
- loc2->owner->cond_exp)))
+ w2->cond_exp)))
return 0;
/* Note that this checks the owner's type, not the location's. In
init_raw_breakpoint_without_location (struct breakpoint *b,
struct gdbarch *gdbarch,
enum bptype bptype,
- struct breakpoint_ops *ops)
+ const struct breakpoint_ops *ops)
{
memset (b, 0, sizeof (*b));
static struct breakpoint *
set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
enum bptype bptype,
- struct breakpoint_ops *ops)
+ const struct breakpoint_ops *ops)
{
struct breakpoint *b = XNEW (struct breakpoint);
static void
init_raw_breakpoint (struct breakpoint *b, struct gdbarch *gdbarch,
struct symtab_and_line sal, enum bptype bptype,
- struct breakpoint_ops *ops)
+ const struct breakpoint_ops *ops)
{
CORE_ADDR adjusted_address;
struct gdbarch *loc_gdbarch;
struct breakpoint *
set_raw_breakpoint (struct gdbarch *gdbarch,
struct symtab_and_line sal, enum bptype bptype,
- struct breakpoint_ops *ops)
+ const struct breakpoint_ops *ops)
{
struct breakpoint *b = XNEW (struct breakpoint);
{
struct fork_catchpoint *c = (struct fork_catchpoint *) b;
struct value_print_options opts;
+ struct ui_out *uiout = current_uiout;
get_user_print_options (&opts);
print_recreate_catch_fork (struct breakpoint *b, struct ui_file *fp)
{
fprintf_unfiltered (fp, "catch fork");
+ print_recreate_thread (b, fp);
}
/* The breakpoint_ops structure to be used in fork catchpoints. */
-static struct breakpoint_ops catch_fork_breakpoint_ops =
-{
- bkpt_dtor,
- bkpt_allocate_location,
- null_re_set,
- insert_catch_fork,
- remove_catch_fork,
- breakpoint_hit_catch_fork,
- null_check_status,
- null_resources_needed,
- null_works_in_software_mode,
- print_it_catch_fork,
- print_one_catch_fork,
- null_print_one_detail,
- print_mention_catch_fork,
- print_recreate_catch_fork
-};
+static struct breakpoint_ops catch_fork_breakpoint_ops;
/* Implement the "insert" breakpoint_ops method for vfork
catchpoints. */
{
struct fork_catchpoint *c = (struct fork_catchpoint *) b;
struct value_print_options opts;
+ struct ui_out *uiout = current_uiout;
get_user_print_options (&opts);
/* Field 4, the address, is omitted (which makes the columns not
print_recreate_catch_vfork (struct breakpoint *b, struct ui_file *fp)
{
fprintf_unfiltered (fp, "catch vfork");
+ print_recreate_thread (b, fp);
}
/* The breakpoint_ops structure to be used in vfork catchpoints. */
-static struct breakpoint_ops catch_vfork_breakpoint_ops =
-{
- bkpt_dtor,
- bkpt_allocate_location,
- null_re_set,
- insert_catch_vfork,
- remove_catch_vfork,
- breakpoint_hit_catch_vfork,
- null_check_status,
- null_resources_needed,
- null_works_in_software_mode,
- print_it_catch_vfork,
- print_one_catch_vfork,
- null_print_one_detail,
- print_mention_catch_vfork,
- print_recreate_catch_vfork
-};
+static struct breakpoint_ops catch_vfork_breakpoint_ops;
/* An instance of this type is used to represent a syscall catchpoint.
It includes a "struct breakpoint" as a kind of base class; users
VEC_free (int, c->syscalls_to_be_caught);
- bkpt_dtor (b);
+ base_breakpoint_ops.dtor (b);
}
/* Implement the "insert" breakpoint_ops method for syscall
{
struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
struct value_print_options opts;
+ struct ui_out *uiout = current_uiout;
get_user_print_options (&opts);
/* Field 4, the address, is omitted (which makes the columns not
fprintf_unfiltered (fp, " %d", s.number);
}
}
+ print_recreate_thread (b, fp);
}
/* The breakpoint_ops structure to be used in syscall catchpoints. */
-static struct breakpoint_ops catch_syscall_breakpoint_ops =
-{
- dtor_catch_syscall,
- bkpt_allocate_location,
- null_re_set,
- insert_catch_syscall,
- remove_catch_syscall,
- breakpoint_hit_catch_syscall,
- null_check_status,
- null_resources_needed,
- null_works_in_software_mode,
- print_it_catch_syscall,
- print_one_catch_syscall,
- null_print_one_detail,
- print_mention_catch_syscall,
- print_recreate_catch_syscall
-};
+static struct breakpoint_ops catch_syscall_breakpoint_ops;
/* Returns non-zero if 'b' is a syscall catchpoint. */
init_catchpoint (struct breakpoint *b,
struct gdbarch *gdbarch, int tempflag,
char *cond_string,
- struct breakpoint_ops *ops)
+ const struct breakpoint_ops *ops)
{
struct symtab_and_line sal;
}
void
-install_breakpoint (struct breakpoint *b)
+install_breakpoint (int internal, struct breakpoint *b)
{
add_to_breakpoint_chain (b);
- set_breakpoint_count (breakpoint_count + 1);
- b->number = breakpoint_count;
- mention (b);
+ set_breakpoint_number (internal, b);
+ if (!internal)
+ mention (b);
observer_notify_breakpoint_created (b);
update_global_location_list (1);
}
static void
create_fork_vfork_event_catchpoint (struct gdbarch *gdbarch,
int tempflag, char *cond_string,
- struct breakpoint_ops *ops)
+ const struct breakpoint_ops *ops)
{
struct fork_catchpoint *c = XNEW (struct fork_catchpoint);
c->forked_inferior_pid = null_ptid;
- install_breakpoint (&c->base);
+ install_breakpoint (0, &c->base);
}
/* Exec catchpoints. */
xfree (c->exec_pathname);
- bkpt_dtor (b);
+ base_breakpoint_ops.dtor (b);
}
static int
{
struct exec_catchpoint *c = (struct exec_catchpoint *) b;
struct value_print_options opts;
+ struct ui_out *uiout = current_uiout;
get_user_print_options (&opts);
print_recreate_catch_exec (struct breakpoint *b, struct ui_file *fp)
{
fprintf_unfiltered (fp, "catch exec");
+ print_recreate_thread (b, fp);
}
-static struct breakpoint_ops catch_exec_breakpoint_ops =
-{
- dtor_catch_exec,
- bkpt_allocate_location,
- null_re_set,
- insert_catch_exec,
- remove_catch_exec,
- breakpoint_hit_catch_exec,
- null_check_status,
- null_resources_needed,
- null_works_in_software_mode,
- print_it_catch_exec,
- print_one_catch_exec,
- null_print_one_detail,
- print_mention_catch_exec,
- print_recreate_catch_exec
-};
+static struct breakpoint_ops catch_exec_breakpoint_ops;
static void
create_syscall_event_catchpoint (int tempflag, VEC(int) *filter,
- struct breakpoint_ops *ops)
+ const struct breakpoint_ops *ops)
{
struct syscall_catchpoint *c;
struct gdbarch *gdbarch = get_current_arch ();
init_catchpoint (&c->base, gdbarch, tempflag, NULL, ops);
c->syscalls_to_be_caught = filter;
- install_breakpoint (&c->base);
+ install_breakpoint (0, &c->base);
}
static int
static struct breakpoint *
momentary_breakpoint_from_master (struct breakpoint *orig,
enum bptype type,
- struct breakpoint_ops *ops)
+ const struct breakpoint_ops *ops)
{
struct breakpoint *copy;
mention (struct breakpoint *b)
{
b->ops->print_mention (b);
- if (ui_out_is_mi_like_p (uiout))
+ if (ui_out_is_mi_like_p (current_uiout))
return;
printf_filtered ("\n");
}
as condition expression. */
static void
-create_breakpoint_sal (struct gdbarch *gdbarch,
- struct symtabs_and_lines sals, char *addr_string,
- char *cond_string,
- enum bptype type, enum bpdisp disposition,
- int thread, int task, int ignore_count,
- struct breakpoint_ops *ops, int from_tty,
- int enabled, int internal, int display_canonical)
+init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
+ struct symtabs_and_lines sals, char *addr_string,
+ char *cond_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, int display_canonical)
{
- struct breakpoint *b = NULL;
int i;
if (type == bp_hardware_breakpoint)
if (i == 0)
{
- b = set_raw_breakpoint (gdbarch, sal, type, ops);
- set_breakpoint_number (internal, b);
+ init_raw_breakpoint (b, gdbarch, sal, type, ops);
b->thread = thread;
b->task = task;
if (type == bp_static_tracepoint)
{
+ struct tracepoint *t = (struct tracepoint *) b;
struct static_tracepoint_marker marker;
if (is_marker_spec (addr_string))
endp = skip_to_space (p);
marker_str = savestring (p, endp - p);
- b->static_trace_marker_id = marker_str;
+ t->static_trace_marker_id = marker_str;
printf_filtered (_("Probed static tracepoint "
"marker \"%s\"\n"),
- b->static_trace_marker_id);
+ t->static_trace_marker_id);
}
else if (target_static_tracepoint_marker_at (sal.pc, &marker))
{
- b->static_trace_marker_id = xstrdup (marker.str_id);
+ t->static_trace_marker_id = xstrdup (marker.str_id);
release_static_tracepoint_marker (&marker);
printf_filtered (_("Probed static tracepoint "
"marker \"%s\"\n"),
- b->static_trace_marker_id);
+ t->static_trace_marker_id);
}
else
warning (_("Couldn't determine the static "
me. */
b->addr_string
= xstrprintf ("*%s", paddress (b->loc->gdbarch, b->loc->address));
+}
- /* Do not mention breakpoints with a negative number, but do
- notify observers. */
- if (!internal)
- mention (b);
- observer_notify_breakpoint_created (b);
+static void
+create_breakpoint_sal (struct gdbarch *gdbarch,
+ struct symtabs_and_lines sals, char *addr_string,
+ char *cond_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, int display_canonical)
+{
+ struct breakpoint *b;
+ struct cleanup *old_chain;
+
+ if (is_tracepoint_type (type))
+ {
+ struct tracepoint *t;
+
+ t = XCNEW (struct tracepoint);
+ b = &t->base;
+ }
+ else
+ b = XNEW (struct breakpoint);
+
+ old_chain = make_cleanup (xfree, b);
+
+ init_breakpoint_sal (b, gdbarch,
+ sals, addr_string,
+ cond_string,
+ type, disposition,
+ thread, task, ignore_count,
+ ops, from_tty,
+ enabled, internal, display_canonical);
+ discard_cleanups (old_chain);
+
+ install_breakpoint (internal, b);
}
/* Remove element at INDEX_TO_REMOVE from SAL, shifting other
char *cond_string,
enum bptype type, enum bpdisp disposition,
int thread, int task, int ignore_count,
- struct breakpoint_ops *ops, int from_tty,
+ const struct breakpoint_ops *ops, int from_tty,
int enabled, int internal)
{
int i;
int tempflag, enum bptype type_wanted,
int ignore_count,
enum auto_boolean pending_break_support,
- struct breakpoint_ops *ops,
+ const struct breakpoint_ops *ops,
int from_tty, int enabled, int internal)
{
volatile struct gdb_exception e;
for (i = 0; i < sals.nelts; ++i)
{
struct symtabs_and_lines expanded;
- struct breakpoint *tp;
+ struct tracepoint *tp;
struct cleanup *old_chain;
expanded.nelts = 1;
expanded.sals[0] = sals.sals[i];
old_chain = make_cleanup (xfree, expanded.sals);
- create_breakpoint_sal (gdbarch, expanded, canonical.canonical[i],
- cond_string, type_wanted,
- tempflag ? disp_del : disp_donttouch,
- thread, task, ignore_count, ops,
- from_tty, enabled, internal,
- canonical.special_display);
-
- do_cleanups (old_chain);
-
- /* Get the tracepoint we just created. */
- if (internal)
- tp = get_breakpoint (internal_breakpoint_number);
- else
- tp = get_breakpoint (breakpoint_count);
- gdb_assert (tp != NULL);
-
+ tp = XCNEW (struct tracepoint);
+ init_breakpoint_sal (&tp->base, gdbarch, expanded,
+ canonical.canonical[i],
+ cond_string, type_wanted,
+ tempflag ? disp_del : disp_donttouch,
+ thread, task, ignore_count, ops,
+ from_tty, enabled, internal,
+ 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
try to match up which of the newly found markers
corresponds to this one */
tp->static_trace_marker_id_idx = i;
+
+ install_breakpoint (internal, &tp->base);
+
+ do_cleanups (old_chain);
}
}
else
{
struct breakpoint *b = bs->breakpoint_at;
struct bp_location *bl = b->loc;
+ struct ui_out *uiout = current_uiout;
gdb_assert (b->type == bp_hardware_breakpoint);
{
struct bp_location *bl = b->loc;
struct value_print_options opts;
+ struct ui_out *uiout = current_uiout;
/* Ranged breakpoints have only one location. */
gdb_assert (bl && bl->next == NULL);
print_mention_ranged_breakpoint (struct breakpoint *b)
{
struct bp_location *bl = b->loc;
+ struct ui_out *uiout = current_uiout;
gdb_assert (bl);
gdb_assert (b->type == bp_hardware_breakpoint);
{
fprintf_unfiltered (fp, "break-range %s, %s", b->addr_string,
b->addr_string_range_end);
+ print_recreate_thread (b, fp);
}
/* The breakpoint_ops structure to be used in ranged breakpoints. */
-static struct breakpoint_ops ranged_breakpoint_ops =
-{
- bkpt_dtor,
- bkpt_allocate_location,
- bkpt_re_set,
- bkpt_insert_location,
- bkpt_remove_location,
- breakpoint_hit_ranged_breakpoint,
- null_check_status,
- resources_needed_ranged_breakpoint,
- null_works_in_software_mode,
- print_it_ranged_breakpoint,
- print_one_ranged_breakpoint,
- print_one_detail_ranged_breakpoint,
- print_mention_ranged_breakpoint,
- print_recreate_ranged_breakpoint
-};
+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
return 1;
}
+/* Implement the "dtor" breakpoint_ops method for watchpoints. */
+
+static void
+dtor_watchpoint (struct breakpoint *self)
+{
+ struct watchpoint *w = (struct watchpoint *) self;
+
+ xfree (w->cond_exp);
+ xfree (w->exp);
+ xfree (w->exp_string);
+ xfree (w->exp_string_reparse);
+ value_free (w->val);
+
+ base_breakpoint_ops.dtor (self);
+}
+
/* Implement the "re_set" breakpoint_ops method for watchpoints. */
static void
re_set_watchpoint (struct breakpoint *b)
{
+ struct watchpoint *w = (struct watchpoint *) b;
+
/* Watchpoint can be either on expression using entirely global
variables, or it can be on local variables.
I'm not sure we'll ever be called in this case.
If a local watchpoint's frame id is still valid, then
- b->exp_valid_block is likewise valid, and we can safely use it.
+ w->exp_valid_block is likewise valid, and we can safely use it.
- Don't do anything about disabled watchpoints, since they will
- be reevaluated again when enabled. */
- update_watchpoint (b, 1 /* reparse */);
+ Don't do anything about disabled watchpoints, since they will be
+ reevaluated again when enabled. */
+ update_watchpoint (w, 1 /* reparse */);
}
/* Implement the "insert" breakpoint_ops method for hardware watchpoints. */
static int
insert_watchpoint (struct bp_location *bl)
{
- int length = bl->owner->exact? 1 : bl->length;
+ struct watchpoint *w = (struct watchpoint *) bl->owner;
+ int length = w->exact ? 1 : bl->length;
return target_insert_watchpoint (bl->address, length, bl->watchpoint_type,
- bl->owner->cond_exp);
+ w->cond_exp);
}
/* Implement the "remove" breakpoint_ops method for hardware watchpoints. */
static int
remove_watchpoint (struct bp_location *bl)
{
- int length = bl->owner->exact? 1 : bl->length;
+ struct watchpoint *w = (struct watchpoint *) bl->owner;
+ int length = w->exact ? 1 : bl->length;
return target_remove_watchpoint (bl->address, length, bl->watchpoint_type,
- bl->owner->cond_exp);
+ w->cond_exp);
}
static int
struct address_space *aspace, CORE_ADDR bp_addr)
{
struct breakpoint *b = bl->owner;
+ struct watchpoint *w = (struct watchpoint *) b;
/* Continuable hardware watchpoints are treated as non-existent if the
reason we stopped wasn't a hardware watchpoint (we didn't stop on
been defined. Also skip watchpoints which we know did not trigger
(did not match the data address). */
if (is_hardware_watchpoint (b)
- && b->watchpoint_triggered == watch_triggered_no)
+ && w->watchpoint_triggered == watch_triggered_no)
return 0;
return 1;
static int
resources_needed_watchpoint (const struct bp_location *bl)
{
- int length = bl->owner->exact? 1 : bl->length;
+ struct watchpoint *w = (struct watchpoint *) bl->owner;
+ int length = w->exact? 1 : bl->length;
return target_region_ok_for_hw_watchpoint (bl->address, length);
}
static int
works_in_software_mode_watchpoint (const struct breakpoint *b)
{
- return b->type == bp_hardware_watchpoint;
+ /* Read and access watchpoints only work with hardware support. */
+ return b->type == bp_watchpoint || b->type == bp_hardware_watchpoint;
}
static enum print_stop_action
const struct bp_location *bl;
struct ui_stream *stb;
enum print_stop_action result;
+ struct watchpoint *w;
+ struct ui_out *uiout = current_uiout;
gdb_assert (bs->bp_location_at != NULL);
bl = bs->bp_location_at;
b = bs->breakpoint_at;
+ w = (struct watchpoint *) b;
stb = ui_out_stream_new (uiout);
old_chain = make_cleanup_ui_out_stream_delete (stb);
watchpoint_value_print (bs->old_val, stb->stream);
ui_out_field_stream (uiout, "old", stb);
ui_out_text (uiout, "\nNew value = ");
- watchpoint_value_print (b->val, stb->stream);
+ watchpoint_value_print (w->val, stb->stream);
ui_out_field_stream (uiout, "new", stb);
ui_out_text (uiout, "\n");
/* More than one watchpoint may have been triggered. */
mention (b);
make_cleanup_ui_out_tuple_begin_end (uiout, "value");
ui_out_text (uiout, "\nValue = ");
- watchpoint_value_print (b->val, stb->stream);
+ watchpoint_value_print (w->val, stb->stream);
ui_out_field_stream (uiout, "value", stb);
ui_out_text (uiout, "\n");
result = PRINT_UNKNOWN;
make_cleanup_ui_out_tuple_begin_end (uiout, "value");
ui_out_text (uiout, "\nValue = ");
}
- watchpoint_value_print (b->val, stb->stream);
+ watchpoint_value_print (w->val, stb->stream);
ui_out_field_stream (uiout, "new", stb);
ui_out_text (uiout, "\n");
result = PRINT_UNKNOWN;
print_mention_watchpoint (struct breakpoint *b)
{
struct cleanup *ui_out_chain;
+ struct watchpoint *w = (struct watchpoint *) b;
+ struct ui_out *uiout = current_uiout;
switch (b->type)
{
ui_out_field_int (uiout, "number", b->number);
ui_out_text (uiout, ": ");
- ui_out_field_string (uiout, "exp", b->exp_string);
+ ui_out_field_string (uiout, "exp", w->exp_string);
do_cleanups (ui_out_chain);
}
static void
print_recreate_watchpoint (struct breakpoint *b, struct ui_file *fp)
{
+ struct watchpoint *w = (struct watchpoint *) b;
+
switch (b->type)
{
case bp_watchpoint:
_("Invalid watchpoint type."));
}
- fprintf_unfiltered (fp, " %s", b->exp_string);
+ fprintf_unfiltered (fp, " %s", w->exp_string);
+ print_recreate_thread (b, fp);
}
/* The breakpoint_ops structure to be used in hardware watchpoints. */
-static struct breakpoint_ops watchpoint_breakpoint_ops =
-{
- bkpt_dtor,
- bkpt_allocate_location,
- re_set_watchpoint,
- insert_watchpoint,
- remove_watchpoint,
- breakpoint_hit_watchpoint,
- check_status_watchpoint,
- resources_needed_watchpoint,
- works_in_software_mode_watchpoint,
- print_it_watchpoint,
- NULL, /* print_one */
- null_print_one_detail,
- print_mention_watchpoint,
- print_recreate_watchpoint
-};
+static struct breakpoint_ops watchpoint_breakpoint_ops;
/* Implement the "insert" breakpoint_ops method for
masked hardware watchpoints. */
static int
insert_masked_watchpoint (struct bp_location *bl)
{
- return target_insert_mask_watchpoint (bl->address, bl->owner->hw_wp_mask,
+ struct watchpoint *w = (struct watchpoint *) bl->owner;
+
+ return target_insert_mask_watchpoint (bl->address, w->hw_wp_mask,
bl->watchpoint_type);
}
static int
remove_masked_watchpoint (struct bp_location *bl)
{
- return target_remove_mask_watchpoint (bl->address, bl->owner->hw_wp_mask,
+ struct watchpoint *w = (struct watchpoint *) bl->owner;
+
+ return target_remove_mask_watchpoint (bl->address, w->hw_wp_mask,
bl->watchpoint_type);
}
static int
resources_needed_masked_watchpoint (const struct bp_location *bl)
{
- return target_masked_watch_num_registers (bl->address,
- bl->owner->hw_wp_mask);
+ struct watchpoint *w = (struct watchpoint *) bl->owner;
+
+ return target_masked_watch_num_registers (bl->address, w->hw_wp_mask);
}
/* Implement the "works_in_software_mode" breakpoint_ops method for
print_it_masked_watchpoint (bpstat bs)
{
struct breakpoint *b = bs->breakpoint_at;
+ struct ui_out *uiout = current_uiout;
/* Masked watchpoints have only one location. */
gdb_assert (b->loc && b->loc->next == NULL);
print_one_detail_masked_watchpoint (const struct breakpoint *b,
struct ui_out *uiout)
{
+ struct watchpoint *w = (struct watchpoint *) b;
+
/* Masked watchpoints have only one location. */
gdb_assert (b->loc && b->loc->next == NULL);
ui_out_text (uiout, "\tmask ");
- ui_out_field_core_addr (uiout, "mask", b->loc->gdbarch, b->hw_wp_mask);
+ ui_out_field_core_addr (uiout, "mask", b->loc->gdbarch, w->hw_wp_mask);
ui_out_text (uiout, "\n");
}
static void
print_mention_masked_watchpoint (struct breakpoint *b)
{
+ struct watchpoint *w = (struct watchpoint *) b;
+ struct ui_out *uiout = current_uiout;
struct cleanup *ui_out_chain;
switch (b->type)
ui_out_field_int (uiout, "number", b->number);
ui_out_text (uiout, ": ");
- ui_out_field_string (uiout, "exp", b->exp_string);
+ ui_out_field_string (uiout, "exp", w->exp_string);
do_cleanups (ui_out_chain);
}
static void
print_recreate_masked_watchpoint (struct breakpoint *b, struct ui_file *fp)
{
+ struct watchpoint *w = (struct watchpoint *) b;
char tmp[40];
switch (b->type)
_("Invalid hardware watchpoint type."));
}
- sprintf_vma (tmp, b->hw_wp_mask);
- fprintf_unfiltered (fp, " %s mask 0x%s", b->exp_string, tmp);
+ sprintf_vma (tmp, w->hw_wp_mask);
+ fprintf_unfiltered (fp, " %s mask 0x%s", w->exp_string, tmp);
+ print_recreate_thread (b, fp);
}
/* The breakpoint_ops structure to be used in masked hardware watchpoints. */
-static struct breakpoint_ops masked_watchpoint_breakpoint_ops =
-{
- bkpt_dtor,
- bkpt_allocate_location,
- re_set_watchpoint,
- insert_masked_watchpoint,
- remove_masked_watchpoint,
- breakpoint_hit_watchpoint,
- check_status_watchpoint,
- resources_needed_masked_watchpoint,
- works_in_software_mode_masked_watchpoint,
- print_it_masked_watchpoint,
- NULL, /* print_one */
- print_one_detail_masked_watchpoint,
- print_mention_masked_watchpoint,
- print_recreate_masked_watchpoint
-};
+static struct breakpoint_ops masked_watchpoint_breakpoint_ops;
/* Tell whether the given watchpoint is a masked hardware watchpoint. */
the hardware watchpoint. */
int use_mask = 0;
CORE_ADDR mask = 0;
+ struct watchpoint *w;
/* Make sure that we actually have parameters to parse. */
if (arg != NULL && arg[0] != '\0')
}
/* Now set up the breakpoint. */
+
+ w = XCNEW (struct watchpoint);
+ b = &w->base;
if (use_mask)
- b = set_raw_breakpoint_without_location (NULL, bp_type,
- &masked_watchpoint_breakpoint_ops);
+ init_raw_breakpoint_without_location (b, NULL, bp_type,
+ &masked_watchpoint_breakpoint_ops);
else
- b = set_raw_breakpoint_without_location (NULL, bp_type,
- &watchpoint_breakpoint_ops);
+ init_raw_breakpoint_without_location (b, NULL, bp_type,
+ &watchpoint_breakpoint_ops);
b->thread = thread;
b->disposition = disp_donttouch;
- b->exp = exp;
- b->exp_valid_block = exp_valid_block;
- b->cond_exp_valid_block = cond_exp_valid_block;
b->pspace = current_program_space;
+ w->exp = exp;
+ w->exp_valid_block = exp_valid_block;
+ w->cond_exp_valid_block = cond_exp_valid_block;
if (just_location)
{
struct type *t = value_type (val);
t = check_typedef (TYPE_TARGET_TYPE (check_typedef (t)));
name = type_to_string (t);
- b->exp_string_reparse = xstrprintf ("* (%s *) %s", name,
+ w->exp_string_reparse = xstrprintf ("* (%s *) %s", name,
core_addr_to_string (addr));
xfree (name);
- b->exp_string = xstrprintf ("-location %.*s",
+ w->exp_string = xstrprintf ("-location %.*s",
(int) (exp_end - exp_start), exp_start);
/* The above expression is in C. */
b->language = language_c;
}
else
- b->exp_string = savestring (exp_start, exp_end - exp_start);
+ w->exp_string = savestring (exp_start, exp_end - exp_start);
if (use_mask)
{
- b->hw_wp_mask = mask;
+ w->hw_wp_mask = mask;
}
else
{
- b->val = val;
- b->val_valid = 1;
+ w->val = val;
+ w->val_valid = 1;
}
if (cond_start)
if (frame)
{
- b->watchpoint_frame = get_frame_id (frame);
- b->watchpoint_thread = inferior_ptid;
+ w->watchpoint_frame = get_frame_id (frame);
+ w->watchpoint_thread = inferior_ptid;
}
else
{
- b->watchpoint_frame = null_frame_id;
- b->watchpoint_thread = null_ptid;
+ w->watchpoint_frame = null_frame_id;
+ w->watchpoint_thread = null_ptid;
}
if (scope_breakpoint != NULL)
{
/* Finally update the new watchpoint. This creates the locations
that should be inserted. */
- update_watchpoint (b, 1);
+ update_watchpoint (w, 1);
}
if (e.reason < 0)
{
throw_exception (e);
}
- set_breakpoint_number (internal, b);
-
- /* Do not mention breakpoints with a negative number, but do
- notify observers. */
- if (!internal)
- mention (b);
- observer_notify_breakpoint_created (b);
-
- update_global_location_list (1);
+ install_breakpoint (internal, b);
}
/* Return count of debug registers needed to watch the given expression.
&catch_exec_breakpoint_ops);
c->exec_pathname = NULL;
- install_breakpoint (&c->base);
+ install_breakpoint (0, &c->base);
}
static enum print_stop_action
print_it_exception_catchpoint (bpstat bs)
{
+ struct ui_out *uiout = current_uiout;
struct breakpoint *b = bs->breakpoint_at;
int bp_temp, bp_throw;
struct bp_location **last_loc)
{
struct value_print_options opts;
+ struct ui_out *uiout = current_uiout;
get_user_print_options (&opts);
if (opts.addressprint)
static void
print_mention_exception_catchpoint (struct breakpoint *b)
{
+ struct ui_out *uiout = current_uiout;
int bp_temp;
int bp_throw;
bp_throw = strstr (b->addr_string, "throw") != NULL;
fprintf_unfiltered (fp, bp_temp ? "tcatch " : "catch ");
fprintf_unfiltered (fp, bp_throw ? "throw" : "catch");
+ print_recreate_thread (b, fp);
}
-static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = {
- bkpt_dtor,
- bkpt_allocate_location,
- bkpt_re_set,
- bkpt_insert_location,
- bkpt_remove_location,
- bkpt_breakpoint_hit,
- bkpt_check_status,
- bkpt_resources_needed,
- null_works_in_software_mode,
- print_it_exception_catchpoint,
- print_one_exception_catchpoint,
- null_print_one_detail,
- print_mention_exception_catchpoint,
- print_recreate_exception_catchpoint
-};
+static struct breakpoint_ops gnu_v3_exception_catchpoint_ops;
static int
handle_gnu_v3_exceptions (int tempflag, char *cond_string,
struct gdbarch *gdbarch,
struct symtab_and_line sal,
char *addr_string,
- struct breakpoint_ops *ops,
+ const struct breakpoint_ops *ops,
int tempflag,
int from_tty)
{
b->language = language_ada;
}
-/* Cleanup function for a syscall filter list. */
-static void
-clean_up_filters (void *arg)
-{
- VEC(int) *iter = *(VEC(int) **) arg;
- VEC_free (int, iter);
-}
-
/* Splits the argument using space as delimiter. Returns an xmalloc'd
filter list, or NULL if no filtering is required. */
static VEC(int) *
catch_syscall_split_args (char *arg)
{
VEC(int) *result = NULL;
- struct cleanup *cleanup = make_cleanup (clean_up_filters, &result);
+ struct cleanup *cleanup = make_cleanup (VEC_cleanup (int), &result);
while (*arg != '\0')
{
}
}
+/* Swap the insertion/duplication state between two locations. */
+
+static void
+swap_insertion (struct bp_location *left, struct bp_location *right)
+{
+ const int left_inserted = left->inserted;
+ const int left_duplicate = left->duplicate;
+ const struct bp_target_info left_target_info = left->target_info;
+
+ left->inserted = right->inserted;
+ left->duplicate = right->duplicate;
+ left->target_info = right->target_info;
+ right->inserted = left_inserted;
+ right->duplicate = left_duplicate;
+ right->target_info = left_target_info;
+}
+
/* If SHOULD_INSERT is false, do not insert any breakpoint locations
into the inferior, only remove already-inserted locations that no
longer should be inserted. Functions that delete a breakpoint or
if (breakpoint_locations_match (loc2, old_loc))
{
- /* For the sake of should_be_inserted.
- Duplicates check below will fix up this
- later. */
- loc2->duplicate = 0;
-
/* Read watchpoint locations are switched to
access watchpoints, if the former are not
supported, but the latter are. */
loc2->watchpoint_type = old_loc->watchpoint_type;
}
- if (loc2 != old_loc && should_be_inserted (loc2))
+ /* loc2 is a duplicated location. We need to check
+ if it should be inserted in case it will be
+ unduplicated. */
+ if (loc2 != old_loc
+ && unduplicated_should_be_inserted (loc2))
{
- loc2->inserted = 1;
- loc2->target_info = old_loc->target_info;
+ swap_insertion (old_loc, loc2);
keep_in_target = 1;
break;
}
continue;
}
+
+ /* This and the above ensure the invariant that the first location
+ is not duplicated, and is the inserted one.
+ All following are marked as duplicated, and are not inserted. */
+ if (loc->inserted)
+ swap_insertion (loc, *loc_first_p);
loc->duplicate = 1;
if ((*loc_first_p)->owner->enable_state == bp_permanent && loc->inserted
static void
say_where (struct breakpoint *b)
{
+ struct ui_out *uiout = current_uiout;
struct value_print_options opts;
get_user_print_options (&opts);
}
}
-/* Default breakpoint_ops methods that do nothing. */
+/* Default bp_location_ops methods. */
-void
-null_re_set (struct breakpoint *b)
+static void
+bp_location_dtor (struct bp_location *self)
+{
+ xfree (self->cond);
+ xfree (self->function_name);
+}
+
+static const struct bp_location_ops bp_location_ops =
+{
+ bp_location_dtor
+};
+
+/* Default breakpoint_ops methods all breakpoint_ops ultimately
+ inherit from. */
+
+static void
+base_breakpoint_dtor (struct breakpoint *self)
+{
+ decref_counted_command_line (&self->commands);
+ xfree (self->cond_string);
+ xfree (self->addr_string);
+ xfree (self->addr_string_range_end);
+ xfree (self->source_file);
+}
+
+static struct bp_location *
+base_breakpoint_allocate_location (struct breakpoint *self)
+{
+ struct bp_location *loc;
+
+ loc = XNEW (struct bp_location);
+ init_bp_location (loc, &bp_location_ops, self);
+ return loc;
+}
+
+static void
+base_breakpoint_re_set (struct breakpoint *b)
{
/* Nothing to re-set. */
}
-void
-null_check_status (bpstat bs)
+#define internal_error_pure_virtual_called() \
+ gdb_assert_not_reached ("pure virtual function called")
+
+static int
+base_breakpoint_insert_location (struct bp_location *bl)
{
- /* nothing */
+ internal_error_pure_virtual_called ();
+}
+
+static int
+base_breakpoint_remove_location (struct bp_location *bl)
+{
+ internal_error_pure_virtual_called ();
+}
+
+static int
+base_breakpoint_breakpoint_hit (const struct bp_location *bl,
+ struct address_space *aspace,
+ CORE_ADDR bp_addr)
+{
+ 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. */
-int
-null_works_in_software_mode (const struct breakpoint *b)
+static int
+base_breakpoint_works_in_software_mode (const struct breakpoint *b)
{
- gdb_assert_not_reached ("null_works_in_software_mode called");
+ internal_error_pure_virtual_called ();
}
/* A "resources_needed" breakpoint_ops method that just internal
errors. */
-int
-null_resources_needed (const struct bp_location *bl)
+static int
+base_breakpoint_resources_needed (const struct bp_location *bl)
{
- gdb_assert_not_reached ("null_resources_needed");
+ internal_error_pure_virtual_called ();
}
-void
-null_print_one_detail (const struct breakpoint *self,
- struct ui_out *uiout)
+static enum print_stop_action
+base_breakpoint_print_it (bpstat bs)
{
- /* nothing */
+ internal_error_pure_virtual_called ();
}
-/* Default bp_location_ops methods. */
-
static void
-bp_location_dtor (struct bp_location *self)
+base_breakpoint_print_one_detail (const struct breakpoint *self,
+ struct ui_out *uiout)
{
- xfree (self->cond);
- xfree (self->function_name);
+ /* nothing */
}
-static const struct bp_location_ops bp_location_ops =
+static void
+base_breakpoint_print_mention (struct breakpoint *b)
{
- bp_location_dtor
-};
-
-/* Default breakpoint_ops methods. */
+ internal_error_pure_virtual_called ();
+}
-void
-bkpt_dtor (struct breakpoint *self)
+static void
+base_breakpoint_print_recreate (struct breakpoint *b, struct ui_file *fp)
{
- decref_counted_command_line (&self->commands);
- xfree (self->cond_string);
- xfree (self->cond_exp);
- xfree (self->addr_string);
- xfree (self->addr_string_range_end);
- xfree (self->exp);
- xfree (self->exp_string);
- xfree (self->exp_string_reparse);
- value_free (self->val);
- xfree (self->source_file);
+ internal_error_pure_virtual_called ();
}
-struct bp_location *
-bkpt_allocate_location (struct breakpoint *self)
+static struct breakpoint_ops base_breakpoint_ops =
{
- struct bp_location *loc;
+ base_breakpoint_dtor,
+ 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,
+ NULL,
+ base_breakpoint_print_one_detail,
+ base_breakpoint_print_mention,
+ base_breakpoint_print_recreate
+};
- loc = XNEW (struct bp_location);
- init_bp_location (loc, &bp_location_ops, self);
- return loc;
-}
+/* Default breakpoint_ops methods. */
-void
+static void
bkpt_re_set (struct breakpoint *b)
{
/* Do not attempt to re-set breakpoints disabled during startup. */
breakpoint_re_set_default (b);
}
-int
+static int
bkpt_insert_location (struct bp_location *bl)
{
if (bl->loc_type == bp_loc_hardware_breakpoint)
&bl->target_info);
}
-int
+static int
bkpt_remove_location (struct bp_location *bl)
{
if (bl->loc_type == bp_loc_hardware_breakpoint)
return target_remove_breakpoint (bl->gdbarch, &bl->target_info);
}
-int
+static int
bkpt_breakpoint_hit (const struct bp_location *bl,
struct address_space *aspace, CORE_ADDR bp_addr)
{
return 1;
}
-void
-bkpt_check_status (bpstat bs)
-{
- /* nothing, always stop */
-}
-
-int
+static int
bkpt_resources_needed (const struct bp_location *bl)
{
gdb_assert (bl->owner->type == bp_hardware_breakpoint);
return 1;
}
-int
-bkpt_works_in_software_mode (const struct breakpoint *b)
-{
- gdb_assert_not_reached ("bkpt_works_in_software_mode called");
-}
-
-enum print_stop_action
+static enum print_stop_action
bkpt_print_it (bpstat bs)
{
- struct cleanup *old_chain;
struct breakpoint *b;
const struct bp_location *bl;
- struct ui_stream *stb;
- int bp_temp = 0;
- enum print_stop_action result;
+ int bp_temp;
+ struct ui_out *uiout = current_uiout;
gdb_assert (bs->bp_location_at != NULL);
bl = bs->bp_location_at;
b = bs->breakpoint_at;
- stb = ui_out_stream_new (uiout);
- old_chain = make_cleanup_ui_out_stream_delete (stb);
-
- switch (b->type)
+ bp_temp = b->disposition == disp_del;
+ if (bl->address != bl->requested_address)
+ breakpoint_adjustment_warning (bl->requested_address,
+ bl->address,
+ b->number, 1);
+ annotate_breakpoint (b->number);
+ if (bp_temp)
+ ui_out_text (uiout, "\nTemporary breakpoint ");
+ else
+ ui_out_text (uiout, "\nBreakpoint ");
+ if (ui_out_is_mi_like_p (uiout))
{
- case bp_breakpoint:
- case bp_hardware_breakpoint:
- bp_temp = b->disposition == disp_del;
- if (bl->address != bl->requested_address)
- breakpoint_adjustment_warning (bl->requested_address,
- bl->address,
- b->number, 1);
- annotate_breakpoint (b->number);
- if (bp_temp)
- ui_out_text (uiout, "\nTemporary breakpoint ");
- else
- ui_out_text (uiout, "\nBreakpoint ");
- if (ui_out_is_mi_like_p (uiout))
- {
- ui_out_field_string (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
- ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
- }
- ui_out_field_int (uiout, "bkptno", b->number);
- ui_out_text (uiout, ", ");
- result = PRINT_SRC_AND_LOC;
- break;
-
- default:
- result = PRINT_UNKNOWN;
- break;
+ ui_out_field_string (uiout, "reason",
+ async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
+ ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
}
+ ui_out_field_int (uiout, "bkptno", b->number);
+ ui_out_text (uiout, ", ");
- do_cleanups (old_chain);
- return result;
+ return PRINT_SRC_AND_LOC;
}
-void
+static void
bkpt_print_mention (struct breakpoint *b)
{
- if (ui_out_is_mi_like_p (uiout))
+ if (ui_out_is_mi_like_p (current_uiout))
return;
switch (b->type)
say_where (b);
}
-void
+static void
bkpt_print_recreate (struct breakpoint *tp, struct ui_file *fp)
{
if (tp->type == bp_breakpoint && tp->disposition == disp_del)
internal_error (__FILE__, __LINE__,
_("unhandled breakpoint type %d"), (int) tp->type);
- if (tp->exp_string)
- fprintf_unfiltered (fp, " %s", tp->exp_string);
- else if (tp->addr_string)
- fprintf_unfiltered (fp, " %s", tp->addr_string);
- else
- {
- char tmp[40];
-
- sprintf_vma (tmp, tp->loc->address);
- fprintf_unfiltered (fp, " *0x%s", tmp);
- }
+ fprintf_unfiltered (fp, " %s", tp->addr_string);
}
-/* The breakpoint_ops structure to be used in regular breakpoints. */
-
-struct breakpoint_ops bkpt_breakpoint_ops =
-{
- bkpt_dtor,
- bkpt_allocate_location,
- bkpt_re_set,
- bkpt_insert_location,
- bkpt_remove_location,
- bkpt_breakpoint_hit,
- bkpt_check_status,
- bkpt_resources_needed,
- null_works_in_software_mode,
- bkpt_print_it,
- NULL, /* print_one */
- null_print_one_detail,
- bkpt_print_mention,
- bkpt_print_recreate
-};
-
/* Virtual table for internal breakpoints. */
static void
static enum print_stop_action
internal_bkpt_print_it (bpstat bs)
{
- struct cleanup *old_chain;
struct breakpoint *b;
- const struct bp_location *bl;
- struct ui_stream *stb;
- int bp_temp = 0;
- enum print_stop_action result;
- gdb_assert (bs->bp_location_at != NULL);
-
- bl = bs->bp_location_at;
b = bs->breakpoint_at;
- stb = ui_out_stream_new (uiout);
- old_chain = make_cleanup_ui_out_stream_delete (stb);
-
switch (b->type)
{
case bp_shlib_event:
variable? (If so, we report this as a generic, "Stopped due
to shlib event" message.) */
printf_filtered (_("Stopped due to shared library event\n"));
- result = PRINT_NOTHING;
break;
case bp_thread_event:
/* Not sure how we will get here.
GDB should not stop for these breakpoints. */
printf_filtered (_("Thread Event Breakpoint: gdb should not stop!\n"));
- result = PRINT_NOTHING;
break;
case bp_overlay_event:
/* By analogy with the thread event, GDB should not stop for these. */
printf_filtered (_("Overlay Event Breakpoint: gdb should not stop!\n"));
- result = PRINT_NOTHING;
break;
case bp_longjmp_master:
/* These should never be enabled. */
printf_filtered (_("Longjmp Master Breakpoint: gdb should not stop!\n"));
- result = PRINT_NOTHING;
break;
case bp_std_terminate_master:
/* These should never be enabled. */
printf_filtered (_("std::terminate Master Breakpoint: "
"gdb should not stop!\n"));
- result = PRINT_NOTHING;
break;
case bp_exception_master:
/* These should never be enabled. */
printf_filtered (_("Exception Master Breakpoint: "
"gdb should not stop!\n"));
- result = PRINT_NOTHING;
- break;
-
- default:
- result = PRINT_UNKNOWN;
break;
}
- do_cleanups (old_chain);
- return result;
+ return PRINT_NOTHING;
}
static void
/* Nothing to mention. These breakpoints are internal. */
}
-static void
-internal_bkpt_print_recreate (struct breakpoint *tp, struct ui_file *fp)
-{
- gdb_assert_not_reached ("internal_bkpt_print_recreate called");
-}
-
-/* The breakpoint_ops structure to be used with internal
- breakpoints. */
-
-static struct breakpoint_ops internal_breakpoint_ops =
-{
- bkpt_dtor,
- bkpt_allocate_location,
- internal_bkpt_re_set,
- bkpt_insert_location,
- bkpt_remove_location,
- bkpt_breakpoint_hit,
- internal_bkpt_check_status,
- bkpt_resources_needed,
- null_works_in_software_mode,
- internal_bkpt_print_it,
- NULL, /* print_one */
- null_print_one_detail,
- internal_bkpt_print_mention,
- internal_bkpt_print_recreate
-};
-
/* Virtual table for momentary breakpoints */
static void
static enum print_stop_action
momentary_bkpt_print_it (bpstat bs)
{
- struct cleanup *old_chain;
- struct breakpoint *b;
- const struct bp_location *bl;
- struct ui_stream *stb;
- int bp_temp = 0;
- enum print_stop_action result;
+ struct ui_out *uiout = current_uiout;
- gdb_assert (bs->bp_location_at != NULL);
-
- bl = bs->bp_location_at;
- b = bs->breakpoint_at;
-
- stb = ui_out_stream_new (uiout);
- old_chain = make_cleanup_ui_out_stream_delete (stb);
-
- switch (b->type)
+ if (ui_out_is_mi_like_p (uiout))
{
- case bp_finish:
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_FUNCTION_FINISHED));
- result = PRINT_UNKNOWN;
- break;
+ struct breakpoint *b = bs->breakpoint_at;
- case bp_until:
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_LOCATION_REACHED));
- result = PRINT_UNKNOWN;
- break;
+ switch (b->type)
+ {
+ case bp_finish:
+ ui_out_field_string
+ (uiout, "reason",
+ async_reason_lookup (EXEC_ASYNC_FUNCTION_FINISHED));
+ break;
- default:
- result = PRINT_UNKNOWN;
- break;
+ case bp_until:
+ ui_out_field_string
+ (uiout, "reason",
+ async_reason_lookup (EXEC_ASYNC_LOCATION_REACHED));
+ break;
+ }
}
- do_cleanups (old_chain);
- return result;
+ return PRINT_UNKNOWN;
}
static void
/* Nothing to mention. These breakpoints are internal. */
}
-static void
-momentary_bkpt_print_recreate (struct breakpoint *tp, struct ui_file *fp)
-{
- gdb_assert_not_reached ("momentary_bkpt_print_recreate called");
-}
-
-/* The breakpoint_ops structure to be used with momentary
- breakpoints. */
-
-static struct breakpoint_ops momentary_breakpoint_ops =
-{
- bkpt_dtor,
- bkpt_allocate_location,
- momentary_bkpt_re_set,
- bkpt_insert_location,
- bkpt_remove_location,
- bkpt_breakpoint_hit,
- momentary_bkpt_check_status,
- bkpt_resources_needed,
- null_works_in_software_mode,
- momentary_bkpt_print_it,
- NULL, /* print_one */
- null_print_one_detail,
- momentary_bkpt_print_mention,
- momentary_bkpt_print_recreate
-};
-
/* The breakpoint_ops structure to be used in tracepoints. */
static void
breakpoint_re_set_default (b);
}
-static int
-tracepoint_insert_location (struct bp_location *bl)
-{
- gdb_assert_not_reached ("tracepoint_insert_location called");
-}
-
-static int
-tracepoint_remove_location (struct bp_location *bl)
-{
- gdb_assert_not_reached ("tracepoint_remove_location called");
-}
-
static int
tracepoint_breakpoint_hit (const struct bp_location *bl,
struct address_space *aspace, CORE_ADDR bp_addr)
return 0;
}
-static void
-tracepoint_check_status (bpstat bs)
-{
- gdb_assert_not_reached ("tracepoint_check_status called");
-}
-
-static int
-tracepoint_works_in_software_mode (const struct breakpoint *b)
-{
- gdb_assert_not_reached ("tracepoint_works_in_software_mode called");
-}
-
-static enum print_stop_action
-tracepoint_print_it (bpstat bs)
-{
- gdb_assert_not_reached ("tracepoint_print_it called");
-}
-
static void
tracepoint_print_one_detail (const struct breakpoint *self,
struct ui_out *uiout)
{
- if (self->static_trace_marker_id)
+ struct tracepoint *tp = (struct tracepoint *) self;
+ if (tp->static_trace_marker_id)
{
gdb_assert (self->type == bp_static_tracepoint);
ui_out_text (uiout, "\tmarker id is ");
ui_out_field_string (uiout, "static-tracepoint-marker-string-id",
- self->static_trace_marker_id);
+ tp->static_trace_marker_id);
ui_out_text (uiout, "\n");
}
}
static void
tracepoint_print_mention (struct breakpoint *b)
{
- if (ui_out_is_mi_like_p (uiout))
+ if (ui_out_is_mi_like_p (current_uiout))
return;
switch (b->type)
}
static void
-tracepoint_print_recreate (struct breakpoint *tp, struct ui_file *fp)
+tracepoint_print_recreate (struct breakpoint *self, struct ui_file *fp)
{
- if (tp->type == bp_fast_tracepoint)
+ struct tracepoint *tp = (struct tracepoint *) self;
+
+ if (self->type == bp_fast_tracepoint)
fprintf_unfiltered (fp, "ftrace");
- if (tp->type == bp_static_tracepoint)
+ if (self->type == bp_static_tracepoint)
fprintf_unfiltered (fp, "strace");
- else if (tp->type == bp_tracepoint)
+ else if (self->type == bp_tracepoint)
fprintf_unfiltered (fp, "trace");
else
internal_error (__FILE__, __LINE__,
- _("unhandled tracepoint type %d"), (int) tp->type);
+ _("unhandled tracepoint type %d"), (int) self->type);
- fprintf_unfiltered (fp, " %s", tp->addr_string);
+ fprintf_unfiltered (fp, " %s", self->addr_string);
+ print_recreate_thread (self, fp);
+
+ if (tp->pass_count)
+ fprintf_unfiltered (fp, " passcount %d\n", tp->pass_count);
}
-struct breakpoint_ops tracepoint_breakpoint_ops =
-{
- bkpt_dtor,
- bkpt_allocate_location,
- tracepoint_re_set,
- tracepoint_insert_location,
- tracepoint_remove_location,
- tracepoint_breakpoint_hit,
- tracepoint_check_status,
- null_resources_needed,
- tracepoint_works_in_software_mode,
- tracepoint_print_it,
- NULL, /* print_one */
- tracepoint_print_one_detail,
- tracepoint_print_mention,
- tracepoint_print_recreate
-};
+struct breakpoint_ops tracepoint_breakpoint_ops;
/* Delete a breakpoint and clean up all traces of it in the data
structures. */
if (bpt->related_breakpoint != bpt)
{
struct breakpoint *related;
+ struct watchpoint *w;
if (bpt->type == bp_watchpoint_scope)
- watchpoint_del_at_next_stop (bpt->related_breakpoint);
+ w = (struct watchpoint *) bpt->related_breakpoint;
else if (bpt->related_breakpoint->type == bp_watchpoint_scope)
- watchpoint_del_at_next_stop (bpt);
+ w = (struct watchpoint *) bpt;
+ else
+ w = NULL;
+ if (w != NULL)
+ watchpoint_del_at_next_stop (w);
/* Unlink bpt from the bpt->related_breakpoint ring. */
for (related = bpt; related->related_breakpoint != bpt;
static struct symtab_and_line
update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
{
+ struct tracepoint *tp = (struct tracepoint *) b;
struct static_tracepoint_marker marker;
CORE_ADDR pc;
int i;
if (target_static_tracepoint_marker_at (pc, &marker))
{
- if (strcmp (b->static_trace_marker_id, marker.str_id) != 0)
+ if (strcmp (tp->static_trace_marker_id, marker.str_id) != 0)
warning (_("static tracepoint %d changed probed marker from %s to %s"),
b->number,
- b->static_trace_marker_id, marker.str_id);
+ tp->static_trace_marker_id, marker.str_id);
- xfree (b->static_trace_marker_id);
- b->static_trace_marker_id = xstrdup (marker.str_id);
+ xfree (tp->static_trace_marker_id);
+ tp->static_trace_marker_id = xstrdup (marker.str_id);
release_static_tracepoint_marker (&marker);
return sal;
if (!sal.explicit_pc
&& sal.line != 0
&& sal.symtab != NULL
- && b->static_trace_marker_id != NULL)
+ && tp->static_trace_marker_id != NULL)
{
VEC(static_tracepoint_marker_p) *markers;
markers
- = target_static_tracepoint_markers_by_strid (b->static_trace_marker_id);
+ = target_static_tracepoint_markers_by_strid (tp->static_trace_marker_id);
if (!VEC_empty(static_tracepoint_marker_p, markers))
{
struct symtab_and_line sal;
struct symbol *sym;
struct static_tracepoint_marker *marker;
+ struct ui_out *uiout = current_uiout;
marker = VEC_index (static_tracepoint_marker_p, markers, 0);
- xfree (b->static_trace_marker_id);
- b->static_trace_marker_id = xstrdup (marker->str_id);
+ xfree (tp->static_trace_marker_id);
+ tp->static_trace_marker_id = xstrdup (marker->str_id);
warning (_("marker for static tracepoint %d (%s) not "
"found at previous line number"),
- b->number, b->static_trace_marker_id);
+ b->number, tp->static_trace_marker_id);
init_sal (&sal);
{
if (marker_spec)
{
+ struct tracepoint *tp = (struct tracepoint *) b;
+
sals = decode_static_tracepoint_spec (&s);
- if (sals.nelts > b->static_trace_marker_id_idx)
+ if (sals.nelts > tp->static_trace_marker_id_idx)
{
- sals.sals[0] = sals.sals[b->static_trace_marker_id_idx];
+ sals.sals[0] = sals.sals[tp->static_trace_marker_id_idx];
sals.nelts = 1;
}
else
- error (_("marker %s not found"), b->static_trace_marker_id);
+ error (_("marker %s not found"), tp->static_trace_marker_id);
}
else
sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, NULL);
TRY_CATCH (e, RETURN_MASK_ALL)
{
+ struct watchpoint *w = (struct watchpoint *) bpt;
+
orig_enable_state = bpt->enable_state;
bpt->enable_state = bp_enabled;
- update_watchpoint (bpt, 1 /* reparse */);
+ update_watchpoint (w, 1 /* reparse */);
}
if (e.reason < 0)
{
ALL_BREAKPOINTS (bp)
if (bp->enable_state == bp_enabled
- && bp->type == bp_hardware_watchpoint
- && bp->val_valid && bp->val)
+ && bp->type == bp_hardware_watchpoint)
{
- struct bp_location *loc;
+ struct watchpoint *wp = (struct watchpoint *) bp;
- for (loc = bp->loc; loc != NULL; loc = loc->next)
- if (loc->loc_type == bp_loc_hardware_watchpoint
- && loc->address + loc->length > addr
- && addr + len > loc->address)
- {
- value_free (bp->val);
- bp->val = NULL;
- bp->val_valid = 0;
- }
+ if (wp->val_valid && wp->val)
+ {
+ struct bp_location *loc;
+
+ for (loc = bp->loc; loc != NULL; loc = loc->next)
+ if (loc->loc_type == bp_loc_hardware_watchpoint
+ && loc->address + loc->length > addr
+ && addr + len > loc->address)
+ {
+ value_free (wp->val);
+ wp->val = NULL;
+ wp->val_valid = 0;
+ }
+ }
}
}
the target does not necessarily have all the information used when
the tracepoint was originally defined. */
-struct breakpoint *
+struct tracepoint *
create_tracepoint_from_upload (struct uploaded_tp *utp)
{
char *addr_str, small_buf[100];
- struct breakpoint *tp;
+ struct tracepoint *tp;
if (utp->at_string)
addr_str = utp->at_string;
if (utp->pass > 0)
{
- sprintf (small_buf, "%d %d", utp->pass, tp->number);
+ sprintf (small_buf, "%d %d", utp->pass, tp->base.number);
trace_pass_command (small_buf, 0);
}
cmd_list = read_command_lines_1 (read_uploaded_action, 1, NULL, NULL);
- breakpoint_set_commands (tp, cmd_list);
+ breakpoint_set_commands (&tp->base, cmd_list);
}
else if (!VEC_empty (char_ptr, utp->actions)
|| !VEC_empty (char_ptr, utp->step_actions))
utp->number);
return tp;
- }
+}
/* Print information on tracepoint number TPNUM_EXP, or all if
omitted. */
static void
tracepoints_info (char *args, int from_tty)
{
+ struct ui_out *uiout = current_uiout;
int num_printed;
num_printed = breakpoint_1 (args, 0, is_tracepoint);
/* Helper function for trace_pass_command. */
static void
-trace_pass_set_count (struct breakpoint *bp, int count, int from_tty)
+trace_pass_set_count (struct tracepoint *tp, int count, int from_tty)
{
- bp->pass_count = count;
- observer_notify_tracepoint_modified (bp->number);
+ tp->pass_count = count;
+ observer_notify_tracepoint_modified (tp->base.number);
if (from_tty)
printf_filtered (_("Setting tracepoint %d's passcount to %d\n"),
- bp->number, count);
+ tp->base.number, count);
}
/* Set passcount for tracepoint.
static void
trace_pass_command (char *args, int from_tty)
{
- struct breakpoint *t1;
+ struct tracepoint *t1;
unsigned int count;
if (args == 0 || *args == 0)
if (*args && strncasecmp (args, "all", 3) == 0)
{
+ struct breakpoint *b;
+
args += 3; /* Skip special argument "all". */
if (*args)
error (_("Junk at end of arguments."));
- ALL_TRACEPOINTS (t1)
+ ALL_TRACEPOINTS (b)
{
+ t1 = (struct tracepoint *) b;
trace_pass_set_count (t1, count, from_tty);
}
}
}
}
-struct breakpoint *
+struct tracepoint *
get_tracepoint (int num)
{
struct breakpoint *t;
ALL_TRACEPOINTS (t)
if (t->number == num)
- return t;
+ return (struct tracepoint *) t;
return NULL;
}
different from the tracepoint number after disconnecting and
reconnecting). */
-struct breakpoint *
+struct tracepoint *
get_tracepoint_by_number_on_target (int num)
{
- struct breakpoint *t;
+ struct breakpoint *b;
- ALL_TRACEPOINTS (t)
- if (t->number_on_target == num)
- return t;
+ ALL_TRACEPOINTS (b)
+ {
+ struct tracepoint *t = (struct tracepoint *) b;
+
+ if (t->number_on_target == num)
+ return t;
+ }
return NULL;
}
If STATE is not NULL, use, get_number_or_range_state and ignore ARG.
If OPTIONAL_P is true, then if the argument is missing, the most
recent tracepoint (tracepoint_count) is returned. */
-struct breakpoint *
+struct tracepoint *
get_tracepoint_by_number (char **arg,
struct get_number_or_range_state *state,
int optional_p)
ALL_TRACEPOINTS (t)
if (t->number == tpnum)
{
- return t;
+ return (struct tracepoint *) t;
}
printf_unfiltered ("No tracepoint number %d.\n", tpnum);
return NULL;
}
+void
+print_recreate_thread (struct breakpoint *b, struct ui_file *fp)
+{
+ if (b->thread != -1)
+ fprintf_unfiltered (fp, " thread %d", b->thread);
+
+ if (b->task != 0)
+ fprintf_unfiltered (fp, " task %d", b->task);
+
+ fprintf_unfiltered (fp, "\n");
+}
+
/* Save information on user settable breakpoints (watchpoints, etc) to
a new script file named FILENAME. If FILTER is non-NULL, call it
on each breakpoint and only include the ones for which it returns
tp->ops->print_recreate (tp, fp);
- if (tp->thread != -1)
- fprintf_unfiltered (fp, " thread %d", tp->thread);
-
- if (tp->task != 0)
- fprintf_unfiltered (fp, " task %d", tp->task);
-
- fprintf_unfiltered (fp, "\n");
-
/* Note, we can't rely on tp->number for anything, as we can't
assume the recreated breakpoint numbers will match. Use $bpnum
instead. */
if (tp->ignore_count)
fprintf_unfiltered (fp, " ignore $bpnum %d\n", tp->ignore_count);
- if (tp->pass_count)
- fprintf_unfiltered (fp, " passcount %d\n", tp->pass_count);
-
if (tp->commands)
{
volatile struct gdb_exception ex;
fprintf_unfiltered (fp, " commands\n");
- ui_out_redirect (uiout, fp);
+ ui_out_redirect (current_uiout, fp);
TRY_CATCH (ex, RETURN_MASK_ALL)
{
- print_command_lines (uiout, tp->commands->commands, 2);
+ print_command_lines (current_uiout, tp->commands->commands, 2);
}
- ui_out_redirect (uiout, NULL);
+ ui_out_redirect (current_uiout, NULL);
if (ex.reason < 0)
throw_exception (ex);
return 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 = base_breakpoint_ops;
+ ops->re_set = bkpt_re_set;
+ ops->insert_location = bkpt_insert_location;
+ ops->remove_location = bkpt_remove_location;
+ ops->breakpoint_hit = bkpt_breakpoint_hit;
+
+ /* The breakpoint_ops structure to be used in regular breakpoints. */
+ ops = &bkpt_breakpoint_ops;
+ *ops = bkpt_base_breakpoint_ops;
+ ops->re_set = bkpt_re_set;
+ 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;
+
+ /* Internal breakpoints. */
+ ops = &internal_breakpoint_ops;
+ *ops = bkpt_base_breakpoint_ops;
+ ops->re_set = internal_bkpt_re_set;
+ ops->check_status = internal_bkpt_check_status;
+ ops->print_it = internal_bkpt_print_it;
+ ops->print_mention = internal_bkpt_print_mention;
+
+ /* Momentary breakpoints. */
+ ops = &momentary_breakpoint_ops;
+ *ops = bkpt_base_breakpoint_ops;
+ ops->re_set = momentary_bkpt_re_set;
+ ops->check_status = momentary_bkpt_check_status;
+ ops->print_it = momentary_bkpt_print_it;
+ ops->print_mention = momentary_bkpt_print_mention;
+
+ /* GNU v3 exception catchpoints. */
+ ops = &gnu_v3_exception_catchpoint_ops;
+ *ops = bkpt_breakpoint_ops;
+ ops->print_it = print_it_exception_catchpoint;
+ ops->print_one = print_one_exception_catchpoint;
+ ops->print_mention = print_mention_exception_catchpoint;
+ ops->print_recreate = print_recreate_exception_catchpoint;
+
+ /* Watchpoints. */
+ ops = &watchpoint_breakpoint_ops;
+ *ops = base_breakpoint_ops;
+ ops->dtor = dtor_watchpoint;
+ ops->re_set = re_set_watchpoint;
+ ops->insert_location = insert_watchpoint;
+ ops->remove_location = remove_watchpoint;
+ ops->breakpoint_hit = breakpoint_hit_watchpoint;
+ ops->check_status = check_status_watchpoint;
+ ops->resources_needed = resources_needed_watchpoint;
+ ops->works_in_software_mode = works_in_software_mode_watchpoint;
+ ops->print_it = print_it_watchpoint;
+ ops->print_mention = print_mention_watchpoint;
+ ops->print_recreate = print_recreate_watchpoint;
+
+ /* Masked watchpoints. */
+ ops = &masked_watchpoint_breakpoint_ops;
+ *ops = watchpoint_breakpoint_ops;
+ ops->insert_location = insert_masked_watchpoint;
+ ops->remove_location = remove_masked_watchpoint;
+ ops->resources_needed = resources_needed_masked_watchpoint;
+ ops->works_in_software_mode = works_in_software_mode_masked_watchpoint;
+ ops->print_it = print_it_masked_watchpoint;
+ ops->print_one_detail = print_one_detail_masked_watchpoint;
+ ops->print_mention = print_mention_masked_watchpoint;
+ ops->print_recreate = print_recreate_masked_watchpoint;
+
+ /* Tracepoints. */
+ ops = &tracepoint_breakpoint_ops;
+ *ops = base_breakpoint_ops;
+ ops->re_set = tracepoint_re_set;
+ ops->breakpoint_hit = tracepoint_breakpoint_hit;
+ ops->print_one_detail = tracepoint_print_one_detail;
+ ops->print_mention = tracepoint_print_mention;
+ ops->print_recreate = tracepoint_print_recreate;
+
+ /* Fork catchpoints. */
+ ops = &catch_fork_breakpoint_ops;
+ *ops = base_breakpoint_ops;
+ ops->insert_location = insert_catch_fork;
+ ops->remove_location = remove_catch_fork;
+ ops->breakpoint_hit = breakpoint_hit_catch_fork;
+ ops->print_it = print_it_catch_fork;
+ ops->print_one = print_one_catch_fork;
+ ops->print_mention = print_mention_catch_fork;
+ ops->print_recreate = print_recreate_catch_fork;
+
+ /* Vfork catchpoints. */
+ ops = &catch_vfork_breakpoint_ops;
+ *ops = base_breakpoint_ops;
+ ops->insert_location = insert_catch_vfork;
+ ops->remove_location = remove_catch_vfork;
+ ops->breakpoint_hit = breakpoint_hit_catch_vfork;
+ ops->print_it = print_it_catch_vfork;
+ ops->print_one = print_one_catch_vfork;
+ ops->print_mention = print_mention_catch_vfork;
+ ops->print_recreate = print_recreate_catch_vfork;
+
+ /* Exec catchpoints. */
+ ops = &catch_exec_breakpoint_ops;
+ *ops = base_breakpoint_ops;
+ ops->dtor = dtor_catch_exec;
+ ops->insert_location = insert_catch_exec;
+ ops->remove_location = remove_catch_exec;
+ ops->breakpoint_hit = breakpoint_hit_catch_exec;
+ ops->print_it = print_it_catch_exec;
+ ops->print_one = print_one_catch_exec;
+ ops->print_mention = print_mention_catch_exec;
+ ops->print_recreate = print_recreate_catch_exec;
+
+ /* Syscall catchpoints. */
+ ops = &catch_syscall_breakpoint_ops;
+ *ops = base_breakpoint_ops;
+ ops->dtor = dtor_catch_syscall;
+ ops->insert_location = insert_catch_syscall;
+ ops->remove_location = remove_catch_syscall;
+ ops->breakpoint_hit = breakpoint_hit_catch_syscall;
+ ops->print_it = print_it_catch_syscall;
+ ops->print_one = print_one_catch_syscall;
+ ops->print_mention = print_mention_catch_syscall;
+ ops->print_recreate = print_recreate_catch_syscall;
+}
+
void
_initialize_breakpoint (void)
{
struct cmd_list_element *c;
+ initialize_breakpoint_ops ();
+
observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib);
observer_attach_inferior_exit (clear_syscall_counts);
observer_attach_memory_changed (invalidate_bp_value_on_memory_change);