#include "xml-syscall.h"
#include "parser-defs.h"
#include "cli/cli-utils.h"
+#include "continuations.h"
/* readline include files */
#include "readline/readline.h"
static void thbreak_command (char *, int);
-static void do_enable_breakpoint (struct breakpoint *, enum bpdisp);
+static void enable_breakpoint_disp (struct breakpoint *, enum bpdisp);
static void stop_command (char *arg, int from_tty);
return 0;
}
-int
-remove_hw_watchpoints (void)
-{
- struct bp_location *bl, **blp_tmp;
- int val = 0;
-
- ALL_BP_LOCATIONS (bl, blp_tmp)
- {
- if (bl->inserted && bl->loc_type == bp_loc_hardware_watchpoint)
- val |= remove_breakpoint (bl, mark_uninserted);
- }
- return val;
-}
-
int
reattach_breakpoints (int pid)
{
}
/* Step-resume breakpoints are meaningless after an exec(). */
- if (b->type == bp_step_resume)
+ if (b->type == bp_step_resume || b->type == bp_hp_step_resume)
{
delete_breakpoint (b);
continue;
case bp_exception:
case bp_exception_resume:
case bp_step_resume:
+ case bp_hp_step_resume:
case bp_watchpoint_scope:
case bp_call_dummy:
case bp_std_terminate:
" 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);
watchpoint_del_at_next_stop (b);
return WP_DELETED;
this_action = BPSTAT_WHAT_SINGLE;
}
break;
+ case bp_hp_step_resume:
+ if (bs->stop)
+ this_action = BPSTAT_WHAT_HP_STEP_RESUME;
+ else
+ {
+ /* It is for the wrong frame. */
+ this_action = BPSTAT_WHAT_SINGLE;
+ }
+ break;
case bp_watchpoint_scope:
case bp_thread_event:
case bp_overlay_event:
{bp_exception, "exception"},
{bp_exception_resume, "exception resume"},
{bp_step_resume, "step resume"},
+ {bp_hp_step_resume, "high-priority step resume"},
{bp_watchpoint_scope, "watchpoint scope"},
{bp_call_dummy, "call dummy"},
{bp_std_terminate, "std::terminate"},
case bp_exception:
case bp_exception_resume:
case bp_step_resume:
+ case bp_hp_step_resume:
case bp_watchpoint_scope:
case bp_call_dummy:
case bp_std_terminate:
case bp_exception:
case bp_exception_resume:
case bp_step_resume:
+ case bp_hp_step_resume:
case bp_watchpoint_scope:
case bp_call_dummy:
case bp_std_terminate:
*blp = NULL;
}
-/* Helper to set_raw_breakpoint below. Creates a breakpoint that has
- type BPTYPE and has no locations as yet. */
-/* This function is used in gdbtk sources and thus can not be made
- static. */
+/* Add breakpoint B at the end of the global breakpoint chain. */
-static struct breakpoint *
-set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
- enum bptype bptype)
+static void
+add_to_breakpoint_chain (struct breakpoint *b)
{
- struct breakpoint *b, *b1;
+ struct breakpoint *b1;
- b = (struct breakpoint *) xmalloc (sizeof (struct breakpoint));
+ /* Add this breakpoint to the end of the chain so that a list of
+ breakpoints will come out in order of increasing numbers. */
+
+ b1 = breakpoint_chain;
+ if (b1 == 0)
+ breakpoint_chain = b;
+ else
+ {
+ while (b1->next)
+ b1 = b1->next;
+ b1->next = b;
+ }
+}
+
+/* Initializes breakpoint B with type BPTYPE and no locations yet. */
+
+static void
+init_raw_breakpoint_without_location (struct breakpoint *b,
+ struct gdbarch *gdbarch,
+ enum bptype bptype)
+{
memset (b, 0, sizeof (*b));
b->type = bptype;
b->ignore_count = 0;
b->commands = NULL;
b->frame_id = null_frame_id;
- b->forked_inferior_pid = null_ptid;
- b->exec_pathname = NULL;
- b->syscalls_to_be_caught = NULL;
b->ops = NULL;
b->condition_not_parsed = 0;
b->py_bp_object = NULL;
b->related_breakpoint = b;
+}
- /* Add this breakpoint to the end of the chain so that a list of
- breakpoints will come out in order of increasing numbers. */
+/* Helper to set_raw_breakpoint below. Creates a breakpoint
+ that has type BPTYPE and has no locations as yet. */
+/* This function is used in gdbtk sources and thus can not be made
+ static. */
- b1 = breakpoint_chain;
- if (b1 == 0)
- breakpoint_chain = b;
- else
- {
- while (b1->next)
- b1 = b1->next;
- b1->next = b;
- }
+static struct breakpoint *
+set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
+ enum bptype bptype)
+{
+ struct breakpoint *b = XNEW (struct breakpoint);
+
+ init_raw_breakpoint_without_location (b, gdbarch, bptype);
+ add_to_breakpoint_chain (b);
return b;
}
return NULL;
}
-/* 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.
+/* 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. 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. */
+ information regarding the creation of a new breakpoint. */
-struct breakpoint *
-set_raw_breakpoint (struct gdbarch *gdbarch,
- struct symtab_and_line sal, enum bptype bptype)
+static void
+init_raw_breakpoint (struct breakpoint *b, struct gdbarch *gdbarch,
+ struct symtab_and_line sal, enum bptype bptype)
{
- struct breakpoint *b = set_raw_breakpoint_without_location (gdbarch,
- bptype);
CORE_ADDR adjusted_address;
struct gdbarch *loc_gdbarch;
+ init_raw_breakpoint_without_location (b, gdbarch, bptype);
+
loc_gdbarch = get_sal_arch (sal);
if (!loc_gdbarch)
loc_gdbarch = b->gdbarch;
sal.explicit_pc || sal.explicit_line);
breakpoints_changed ();
+}
+/* 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. */
+
+struct breakpoint *
+set_raw_breakpoint (struct gdbarch *gdbarch,
+ struct symtab_and_line sal, enum bptype bptype)
+{
+ struct breakpoint *b = XNEW (struct breakpoint);
+
+ init_raw_breakpoint (b, gdbarch, sal, bptype);
+ add_to_breakpoint_chain (b);
return b;
}
/* FORK & VFORK catchpoints. */
+/* An instance of this type is used to represent a fork or vfork
+ catchpoint. It includes a "struct breakpoint" as a kind of base
+ class; users downcast to "struct breakpoint *" when needed. A
+ breakpoint is really of this type iff its ops pointer points to
+ CATCH_FORK_BREAKPOINT_OPS. */
+
+struct fork_catchpoint
+{
+ /* The base class. */
+ struct breakpoint base;
+
+ /* Process id of a child process whose forking triggered this
+ catchpoint. This field is only valid immediately after this
+ catchpoint has triggered. */
+ ptid_t forked_inferior_pid;
+};
+
/* Implement the "insert" breakpoint_ops method for fork
catchpoints. */
breakpoint_hit_catch_fork (const struct bp_location *bl,
struct address_space *aspace, CORE_ADDR bp_addr)
{
- return inferior_has_forked (inferior_ptid, &bl->owner->forked_inferior_pid);
+ struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner;
+
+ return inferior_has_forked (inferior_ptid, &c->forked_inferior_pid);
}
/* Implement the "print_it" breakpoint_ops method for fork
static enum print_stop_action
print_it_catch_fork (struct breakpoint *b)
{
+ struct fork_catchpoint *c = (struct fork_catchpoint *) b;
+
annotate_catchpoint (b->number);
printf_filtered (_("\nCatchpoint %d (forked process %d), "),
- b->number, ptid_get_pid (b->forked_inferior_pid));
+ b->number, ptid_get_pid (c->forked_inferior_pid));
return PRINT_SRC_AND_LOC;
}
static void
print_one_catch_fork (struct breakpoint *b, struct bp_location **last_loc)
{
+ struct fork_catchpoint *c = (struct fork_catchpoint *) b;
struct value_print_options opts;
get_user_print_options (&opts);
ui_out_field_skip (uiout, "addr");
annotate_field (5);
ui_out_text (uiout, "fork");
- if (!ptid_equal (b->forked_inferior_pid, null_ptid))
+ if (!ptid_equal (c->forked_inferior_pid, null_ptid))
{
ui_out_text (uiout, ", process ");
ui_out_field_int (uiout, "what",
- ptid_get_pid (b->forked_inferior_pid));
+ ptid_get_pid (c->forked_inferior_pid));
ui_out_spaces (uiout, 1);
}
}
static struct breakpoint_ops catch_fork_breakpoint_ops =
{
+ NULL, /* dtor */
insert_catch_fork,
remove_catch_fork,
breakpoint_hit_catch_fork,
breakpoint_hit_catch_vfork (const struct bp_location *bl,
struct address_space *aspace, CORE_ADDR bp_addr)
{
- return inferior_has_vforked (inferior_ptid, &bl->owner->forked_inferior_pid);
+ struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner;
+
+ return inferior_has_vforked (inferior_ptid, &c->forked_inferior_pid);
}
/* Implement the "print_it" breakpoint_ops method for vfork
static enum print_stop_action
print_it_catch_vfork (struct breakpoint *b)
{
+ struct fork_catchpoint *c = (struct fork_catchpoint *) b;
+
annotate_catchpoint (b->number);
printf_filtered (_("\nCatchpoint %d (vforked process %d), "),
- b->number, ptid_get_pid (b->forked_inferior_pid));
+ b->number, ptid_get_pid (c->forked_inferior_pid));
return PRINT_SRC_AND_LOC;
}
static void
print_one_catch_vfork (struct breakpoint *b, struct bp_location **last_loc)
{
+ struct fork_catchpoint *c = (struct fork_catchpoint *) b;
struct value_print_options opts;
get_user_print_options (&opts);
ui_out_field_skip (uiout, "addr");
annotate_field (5);
ui_out_text (uiout, "vfork");
- if (!ptid_equal (b->forked_inferior_pid, null_ptid))
+ if (!ptid_equal (c->forked_inferior_pid, null_ptid))
{
ui_out_text (uiout, ", process ");
ui_out_field_int (uiout, "what",
- ptid_get_pid (b->forked_inferior_pid));
+ ptid_get_pid (c->forked_inferior_pid));
ui_out_spaces (uiout, 1);
}
}
static struct breakpoint_ops catch_vfork_breakpoint_ops =
{
+ NULL, /* dtor */
insert_catch_vfork,
remove_catch_vfork,
breakpoint_hit_catch_vfork,
print_recreate_catch_vfork
};
+/* An instance of this type is used to represent a syscall catchpoint.
+ It includes a "struct breakpoint" as a kind of base class; users
+ downcast to "struct breakpoint *" when needed. A breakpoint is
+ really of this type iff its ops pointer points to
+ CATCH_SYSCALL_BREAKPOINT_OPS. */
+
+struct syscall_catchpoint
+{
+ /* The base class. */
+ struct breakpoint base;
+
+ /* Syscall numbers used for the 'catch syscall' feature. If no
+ syscall has been specified for filtering, its value is NULL.
+ Otherwise, it holds a list of all syscalls to be caught. The
+ list elements are allocated with xmalloc. */
+ VEC(int) *syscalls_to_be_caught;
+};
+
+/* Implement the "dtor" breakpoint_ops method for syscall
+ catchpoints. */
+
+static void
+dtor_catch_syscall (struct breakpoint *b)
+{
+ struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
+
+ VEC_free (int, c->syscalls_to_be_caught);
+}
+
/* Implement the "insert" breakpoint_ops method for syscall
catchpoints. */
static int
insert_catch_syscall (struct bp_location *bl)
{
+ struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
struct inferior *inf = current_inferior ();
++inf->total_syscalls_count;
- if (!bl->owner->syscalls_to_be_caught)
+ if (!c->syscalls_to_be_caught)
++inf->any_syscall_count;
else
{
int i, iter;
for (i = 0;
- VEC_iterate (int, bl->owner->syscalls_to_be_caught, i, iter);
+ VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
i++)
{
int elem;
static int
remove_catch_syscall (struct bp_location *bl)
{
+ struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
struct inferior *inf = current_inferior ();
--inf->total_syscalls_count;
- if (!bl->owner->syscalls_to_be_caught)
+ if (!c->syscalls_to_be_caught)
--inf->any_syscall_count;
else
{
int i, iter;
for (i = 0;
- VEC_iterate (int, bl->owner->syscalls_to_be_caught, i, iter);
+ VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
i++)
{
int elem;
breakpoint. If we are, then we must guarantee that the called
syscall is the same syscall we are catching. */
int syscall_number = 0;
- const struct breakpoint *b = bl->owner;
+ const struct syscall_catchpoint *c
+ = (const struct syscall_catchpoint *) bl->owner;
if (!inferior_has_called_syscall (inferior_ptid, &syscall_number))
return 0;
/* Now, checking if the syscall is the same. */
- if (b->syscalls_to_be_caught)
+ if (c->syscalls_to_be_caught)
{
int i, iter;
for (i = 0;
- VEC_iterate (int, b->syscalls_to_be_caught, i, iter);
+ VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
i++)
if (syscall_number == iter)
break;
print_one_catch_syscall (struct breakpoint *b,
struct bp_location **last_loc)
{
+ struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
struct value_print_options opts;
get_user_print_options (&opts);
ui_out_field_skip (uiout, "addr");
annotate_field (5);
- if (b->syscalls_to_be_caught
- && VEC_length (int, b->syscalls_to_be_caught) > 1)
+ if (c->syscalls_to_be_caught
+ && VEC_length (int, c->syscalls_to_be_caught) > 1)
ui_out_text (uiout, "syscalls \"");
else
ui_out_text (uiout, "syscall \"");
- if (b->syscalls_to_be_caught)
+ if (c->syscalls_to_be_caught)
{
int i, iter;
char *text = xstrprintf ("%s", "");
for (i = 0;
- VEC_iterate (int, b->syscalls_to_be_caught, i, iter);
+ VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
i++)
{
char *x = text;
static void
print_mention_catch_syscall (struct breakpoint *b)
{
- if (b->syscalls_to_be_caught)
+ struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
+
+ if (c->syscalls_to_be_caught)
{
int i, iter;
- if (VEC_length (int, b->syscalls_to_be_caught) > 1)
+ if (VEC_length (int, c->syscalls_to_be_caught) > 1)
printf_filtered (_("Catchpoint %d (syscalls"), b->number);
else
printf_filtered (_("Catchpoint %d (syscall"), b->number);
for (i = 0;
- VEC_iterate (int, b->syscalls_to_be_caught, i, iter);
+ VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
i++)
{
struct syscall s;
static void
print_recreate_catch_syscall (struct breakpoint *b, struct ui_file *fp)
{
+ struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
+
fprintf_unfiltered (fp, "catch syscall");
- if (b->syscalls_to_be_caught)
+ if (c->syscalls_to_be_caught)
{
int i, iter;
for (i = 0;
- VEC_iterate (int, b->syscalls_to_be_caught, i, iter);
+ VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
i++)
{
struct syscall s;
static struct breakpoint_ops catch_syscall_breakpoint_ops =
{
+ dtor_catch_syscall,
insert_catch_syscall,
remove_catch_syscall,
breakpoint_hit_catch_syscall,
return (b->ops == &catch_syscall_breakpoint_ops);
}
-/* Create a new breakpoint of the bp_catchpoint kind and return it,
- but does NOT mention it nor update the global location list.
- This is useful if you need to fill more fields in the
- struct breakpoint before calling mention.
-
- If TEMPFLAG is non-zero, then make the breakpoint temporary.
- If COND_STRING is not NULL, then store it in the breakpoint.
- OPS, if not NULL, is the breakpoint_ops structure associated
- to the catchpoint. */
+/* Initialize a new breakpoint of the bp_catchpoint kind. If TEMPFLAG
+ is non-zero, then make the breakpoint temporary. If COND_STRING is
+ not NULL, then store it in the breakpoint. OPS, if not NULL, is
+ the breakpoint_ops structure associated to the catchpoint. */
-static struct breakpoint *
-create_catchpoint_without_mention (struct gdbarch *gdbarch, int tempflag,
- char *cond_string,
- struct breakpoint_ops *ops)
+static void
+init_catchpoint (struct breakpoint *b,
+ struct gdbarch *gdbarch, int tempflag,
+ char *cond_string,
+ struct breakpoint_ops *ops)
{
struct symtab_and_line sal;
- struct breakpoint *b;
+
+ memset (b, 0, sizeof (*b));
init_sal (&sal);
sal.pspace = current_program_space;
- b = set_raw_breakpoint (gdbarch, sal, bp_catchpoint);
- set_breakpoint_count (breakpoint_count + 1);
- b->number = breakpoint_count;
+ init_raw_breakpoint (b, gdbarch, sal, bp_catchpoint);
b->cond_string = (cond_string == NULL) ? NULL : xstrdup (cond_string);
b->thread = -1;
b->enable_state = bp_enabled;
b->disposition = tempflag ? disp_del : disp_donttouch;
b->ops = ops;
-
- return b;
}
-/* Create a new breakpoint of the bp_catchpoint kind and return it.
-
- If TEMPFLAG is non-zero, then make the breakpoint temporary.
- If COND_STRING is not NULL, then store it in the breakpoint.
- OPS, if not NULL, is the breakpoint_ops structure associated
- to the catchpoint. */
+/* Add breakpoint B on the breakpoint list, and notify the user, the
+ target and breakpoint_created observers of its existence. */
-static struct breakpoint *
-create_catchpoint (struct gdbarch *gdbarch, int tempflag,
- char *cond_string, struct breakpoint_ops *ops)
+static void
+install_catchpoint (struct breakpoint *b)
{
- struct breakpoint *b =
- create_catchpoint_without_mention (gdbarch, tempflag, cond_string, ops);
-
+ add_to_breakpoint_chain (b);
+ set_breakpoint_count (breakpoint_count + 1);
+ b->number = breakpoint_count;
mention (b);
observer_notify_breakpoint_created (b);
update_global_location_list (1);
-
- return b;
}
static void
int tempflag, char *cond_string,
struct breakpoint_ops *ops)
{
- struct breakpoint *b
- = create_catchpoint (gdbarch, tempflag, cond_string, ops);
+ struct fork_catchpoint *c = XNEW (struct fork_catchpoint);
- /* FIXME: We should put this information in a breakpoint private data
- area. */
- b->forked_inferior_pid = null_ptid;
+ init_catchpoint (&c->base, gdbarch, tempflag, cond_string, ops);
+
+ c->forked_inferior_pid = null_ptid;
+
+ install_catchpoint (&c->base);
}
/* Exec catchpoints. */
+/* An instance of this type is used to represent an exec catchpoint.
+ It includes a "struct breakpoint" as a kind of base class; users
+ downcast to "struct breakpoint *" when needed. A breakpoint is
+ really of this type iff its ops pointer points to
+ CATCH_EXEC_BREAKPOINT_OPS. */
+
+struct exec_catchpoint
+{
+ /* The base class. */
+ struct breakpoint base;
+
+ /* Filename of a program whose exec triggered this catchpoint.
+ This field is only valid immediately after this catchpoint has
+ triggered. */
+ char *exec_pathname;
+};
+
+/* Implement the "dtor" breakpoint_ops method for exec
+ catchpoints. */
+
+static void
+dtor_catch_exec (struct breakpoint *b)
+{
+ struct exec_catchpoint *c = (struct exec_catchpoint *) b;
+
+ xfree (c->exec_pathname);
+}
+
static int
insert_catch_exec (struct bp_location *bl)
{
breakpoint_hit_catch_exec (const struct bp_location *bl,
struct address_space *aspace, CORE_ADDR bp_addr)
{
- return inferior_has_execd (inferior_ptid, &bl->owner->exec_pathname);
+ struct exec_catchpoint *c = (struct exec_catchpoint *) bl->owner;
+
+ return inferior_has_execd (inferior_ptid, &c->exec_pathname);
}
static enum print_stop_action
print_it_catch_exec (struct breakpoint *b)
{
+ struct exec_catchpoint *c = (struct exec_catchpoint *) b;
+
annotate_catchpoint (b->number);
printf_filtered (_("\nCatchpoint %d (exec'd %s), "), b->number,
- b->exec_pathname);
+ c->exec_pathname);
return PRINT_SRC_AND_LOC;
}
static void
print_one_catch_exec (struct breakpoint *b, struct bp_location **last_loc)
{
+ struct exec_catchpoint *c = (struct exec_catchpoint *) b;
struct value_print_options opts;
get_user_print_options (&opts);
ui_out_field_skip (uiout, "addr");
annotate_field (5);
ui_out_text (uiout, "exec");
- if (b->exec_pathname != NULL)
+ if (c->exec_pathname != NULL)
{
ui_out_text (uiout, ", program \"");
- ui_out_field_string (uiout, "what", b->exec_pathname);
+ ui_out_field_string (uiout, "what", c->exec_pathname);
ui_out_text (uiout, "\" ");
}
}
static struct breakpoint_ops catch_exec_breakpoint_ops =
{
+ dtor_catch_exec,
insert_catch_exec,
remove_catch_exec,
breakpoint_hit_catch_exec,
create_syscall_event_catchpoint (int tempflag, VEC(int) *filter,
struct breakpoint_ops *ops)
{
+ struct syscall_catchpoint *c;
struct gdbarch *gdbarch = get_current_arch ();
- struct breakpoint *b =
- create_catchpoint_without_mention (gdbarch, tempflag, NULL, ops);
- b->syscalls_to_be_caught = filter;
+ c = XNEW (struct syscall_catchpoint);
+ init_catchpoint (&c->base, gdbarch, tempflag, NULL, ops);
+ c->syscalls_to_be_caught = filter;
- /* Now, we have to mention the breakpoint and update the global
- location list. */
- mention (b);
- observer_notify_breakpoint_created (b);
- update_global_location_list (1);
+ install_catchpoint (&c->base);
}
static int
case bp_exception:
case bp_exception_resume:
case bp_step_resume:
+ case bp_hp_step_resume:
case bp_call_dummy:
case bp_std_terminate:
case bp_watchpoint_scope:
static struct breakpoint_ops ranged_breakpoint_ops =
{
+ NULL, /* dtor */
NULL, /* insert */
NULL, /* remove */
breakpoint_hit_ranged_breakpoint,
static struct breakpoint_ops watchpoint_breakpoint_ops =
{
+ NULL, /* dtor */
insert_watchpoint,
remove_watchpoint,
NULL, /* breakpoint_hit */
static struct breakpoint_ops masked_watchpoint_breakpoint_ops =
{
+ NULL, /* dtor */
insert_masked_watchpoint,
remove_masked_watchpoint,
NULL, /* breakpoint_hit */
care of cleaning up the temporary breakpoints set up by the until
command. */
static void
-until_break_command_continuation (void *arg)
+until_break_command_continuation (void *arg, int err)
{
struct until_break_command_continuation_args *a = arg;
catch_exec_command_1 (char *arg, int from_tty,
struct cmd_list_element *command)
{
+ struct exec_catchpoint *c;
struct gdbarch *gdbarch = get_current_arch ();
int tempflag;
char *cond_string = NULL;
if ((*arg != '\0') && !isspace (*arg))
error (_("Junk at end of arguments."));
- /* If this target supports it, create an exec catchpoint
- and enable reporting of such events. */
- create_catchpoint (gdbarch, tempflag, cond_string,
- &catch_exec_breakpoint_ops);
+ c = XNEW (struct exec_catchpoint);
+ init_catchpoint (&c->base, gdbarch, tempflag, cond_string,
+ &catch_exec_breakpoint_ops);
+ c->exec_pathname = NULL;
+
+ install_catchpoint (&c->base);
}
static enum print_stop_action
}
static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = {
+ NULL, /* dtor */
NULL, /* insert */
NULL, /* remove */
NULL, /* breakpoint_hit */
break;
}
+ if (bpt->ops != NULL && bpt->ops->dtor != NULL)
+ bpt->ops->dtor (bpt);
+
decref_counted_command_line (&bpt->commands);
xfree (bpt->cond_string);
xfree (bpt->cond_exp);
xfree (bpt->exp_string_reparse);
value_free (bpt->val);
xfree (bpt->source_file);
- xfree (bpt->exec_pathname);
- clean_up_filters (&bpt->syscalls_to_be_caught);
/* Be sure no bpstat's are pointing at the breakpoint after it's
return make_cleanup (do_delete_breakpoint_cleanup, b);
}
-/* A callback for map_breakpoint_numbers that calls
- delete_breakpoint. */
+/* Iterator function to call a user-provided callback function once
+ for each of B and its related breakpoints. */
+
+static void
+iterate_over_related_breakpoints (struct breakpoint *b,
+ void (*function) (struct breakpoint *,
+ void *),
+ void *data)
+{
+ struct breakpoint *related;
+
+ related = b;
+ do
+ {
+ struct breakpoint *next;
+
+ /* FUNCTION may delete RELATED. */
+ next = related->related_breakpoint;
+
+ if (next == related)
+ {
+ /* RELATED is the last ring entry. */
+ function (related, data);
+
+ /* FUNCTION may have deleted it, so we'd never reach back to
+ B. There's nothing left to do anyway, so just break
+ out. */
+ break;
+ }
+ else
+ function (related, data);
+
+ related = next;
+ }
+ while (related != b);
+}
static void
do_delete_breakpoint (struct breakpoint *b, void *ignore)
delete_breakpoint (b);
}
+/* A callback for map_breakpoint_numbers that calls
+ delete_breakpoint. */
+
+static void
+do_map_delete_breakpoint (struct breakpoint *b, void *ignore)
+{
+ iterate_over_related_breakpoints (b, do_delete_breakpoint, NULL);
+}
+
void
delete_command (char *arg, int from_tty)
{
}
}
else
- map_breakpoint_numbers (arg, do_delete_breakpoint, NULL);
+ map_breakpoint_numbers (arg, do_map_delete_breakpoint, NULL);
}
static int
case bp_call_dummy:
case bp_std_terminate:
case bp_step_resume:
+ case bp_hp_step_resume:
case bp_longjmp:
case bp_longjmp_resume:
case bp_exception:
ALL_BREAKPOINTS_SAFE (b, tmp)
if (b->number == num)
{
- struct breakpoint *related_breakpoint;
-
match = 1;
- related_breakpoint = b;
- do
- {
- struct breakpoint *next_related_b;
-
- /* FUNCTION can be also delete_breakpoint. */
- next_related_b = related_breakpoint->related_breakpoint;
- function (related_breakpoint, data);
-
- /* For delete_breakpoint of the last entry of the ring we
- were traversing we would never get back to B. */
- if (next_related_b == related_breakpoint)
- break;
- related_breakpoint = next_related_b;
- }
- while (related_breakpoint != b);
+ function (b, data);
break;
}
if (match == 0)
observer_notify_breakpoint_modified (bpt);
}
+/* A callback for iterate_over_related_breakpoints. */
+
+static void
+do_disable_breakpoint (struct breakpoint *b, void *ignore)
+{
+ disable_breakpoint (b);
+}
+
/* A callback for map_breakpoint_numbers that calls
disable_breakpoint. */
static void
do_map_disable_breakpoint (struct breakpoint *b, void *ignore)
{
- disable_breakpoint (b);
+ iterate_over_related_breakpoints (b, do_disable_breakpoint, NULL);
}
static void
}
static void
-do_enable_breakpoint (struct breakpoint *bpt, enum bpdisp disposition)
+enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition)
{
int target_resources_ok;
void
enable_breakpoint (struct breakpoint *bpt)
{
- do_enable_breakpoint (bpt, bpt->disposition);
+ enable_breakpoint_disp (bpt, bpt->disposition);
+}
+
+static void
+do_enable_breakpoint (struct breakpoint *bpt, void *arg)
+{
+ enable_breakpoint (bpt);
}
/* A callback for map_breakpoint_numbers that calls
static void
do_map_enable_breakpoint (struct breakpoint *b, void *ignore)
{
- enable_breakpoint (b);
+ iterate_over_related_breakpoints (b, do_enable_breakpoint, NULL);
}
/* The enable command enables the specified breakpoints (or all defined
}
static void
-enable_once_breakpoint (struct breakpoint *bpt, void *ignore)
+do_enable_breakpoint_disp (struct breakpoint *bpt, void *arg)
{
- do_enable_breakpoint (bpt, disp_disable);
+ enum bpdisp disp = *(enum bpdisp *) arg;
+
+ enable_breakpoint_disp (bpt, disp);
+}
+
+static void
+do_map_enable_once_breakpoint (struct breakpoint *bpt, void *ignore)
+{
+ enum bpdisp disp = disp_disable;
+
+ iterate_over_related_breakpoints (bpt, do_enable_breakpoint_disp, &disp);
}
static void
enable_once_command (char *args, int from_tty)
{
- map_breakpoint_numbers (args, enable_once_breakpoint, NULL);
+ map_breakpoint_numbers (args, do_map_enable_once_breakpoint, NULL);
}
static void
-enable_delete_breakpoint (struct breakpoint *bpt, void *ignore)
+do_map_enable_delete_breakpoint (struct breakpoint *bpt, void *ignore)
{
- do_enable_breakpoint (bpt, disp_del);
+ enum bpdisp disp = disp_del;
+
+ iterate_over_related_breakpoints (bpt, do_enable_breakpoint_disp, &disp);
}
static void
enable_delete_command (char *args, int from_tty)
{
- map_breakpoint_numbers (args, enable_delete_breakpoint, NULL);
+ map_breakpoint_numbers (args, do_map_enable_delete_breakpoint, NULL);
}
\f
static void
ALL_BREAKPOINTS (bp)
if (is_syscall_catchpoint_enabled (bp))
{
- if (bp->syscalls_to_be_caught)
+ struct syscall_catchpoint *c = (struct syscall_catchpoint *) bp;
+
+ if (c->syscalls_to_be_caught)
{
int i, iter;
for (i = 0;
- VEC_iterate (int, bp->syscalls_to_be_caught, i, iter);
+ VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
i++)
if (syscall_number == iter)
return 1;
}
}
else
- map_breakpoint_numbers (arg, do_delete_breakpoint, NULL);
+ map_breakpoint_numbers (arg, do_map_delete_breakpoint, NULL);
}
/* Helper function for trace_pass_command. */
Disable some breakpoints.\n\
Arguments are breakpoint numbers with spaces in between.\n\
To disable all breakpoints, give no argument.\n\
-A disabled breakpoint is not forgotten, but has no effect until reenabled."),
+A disabled breakpoint is not forgotten, but has no effect until re-enabled."),
&disablelist, "disable ", 1, &cmdlist);
add_com_alias ("dis", "disable", class_breakpoint, 1);
add_com_alias ("disa", "disable", class_breakpoint, 1);
Disable some breakpoints.\n\
Arguments are breakpoint numbers with spaces in between.\n\
To disable all breakpoints, give no argument.\n\
-A disabled breakpoint is not forgotten, but has no effect until reenabled."));
+A disabled breakpoint is not forgotten, but has no effect until re-enabled."));
add_cmd ("breakpoints", class_alias, disable_command, _("\
Disable some breakpoints.\n\
Arguments are breakpoint numbers with spaces in between.\n\
To disable all breakpoints, give no argument.\n\
-A disabled breakpoint is not forgotten, but has no effect until reenabled.\n\
+A disabled breakpoint is not forgotten, but has no effect until re-enabled.\n\
This command may be abbreviated \"disable\"."),
&disablelist);