* breakpoint.h (enum bptype): New enum bp_catchpoint.

Delete bp_catch_fork and bp_catch_vfork.
        (struct breakpoint_ops): Add new methods "insert", "remove"
        and "breakpoint_hit".
        * breakpoint.c (create_fork_vfork_event_catchpoint)
        (create_fork_event_catchpoint, create_vfork_event_catchpoint): Remove.
        (insert_catchpoint): Remove handling of bp_catch_fork and
        bp_catch_vfork catchpoints, and handle them as bp_catchpoint
        catchpoints instead.
        (insert_bp_location, update_breakpoints_after_exec)
        (remove_breakpoint, bpstat_check_location, bpstat_what)
        (allocate_bp_location): Likewise.
        (print_it_typical, print_one_breakpoint_location, mention): Remove
        handling of bp_catch_fork and bp_catch_vfork breakpoints.
        (ep_is_catchpoint, user_settable_breakpoint)
        (breakpoint_address_is_meaningful, adjust_breakpoint_address)
        (breakpoint_re_set_one, disable_command, enable_command):
        Remove use of bp_catch_fork and bp_catch_vfork.  Add handling of
        bp_catchpoint breakpoints.
        (insert_catch_fork, remove_catch_fork, breakpoint_hit_catch_fork)
        (print_it_catch_fork, print_one_catch_fork, print_mention_catch_fork):
        New functions.
        (catch_fork_breakpoint_ops): New static constant.
        (insert_catch_vfork, remove_catch_vfork, breakpoint_hit_catch_vfork)
        (print_it_catch_vfork, print_one_catch_vfork)
        (print_mention_catch_vfork): New functions.
        (catch_vfork_breakpoint_ops): New static constant.
        (create_catchpoint, create_fork_vfork_event_catchpoint): New functions.
        (catch_fork_command_1): Use create_fork_vfork_event_catchpoint
        to create the fork and vfork catchpoints.
        (gnu_v3_exception_catchpoint_ops): Set new breakpoint_ops fields.
        * ada-lang.c (catch_exception_breakpoint_ops): Set new breakpoint_ops
        fields.
        (catch_exception_unhandled_breakpoint_ops): Likewise.
        (catch_assert_breakpoint_ops): Likewise.
This commit is contained in:
Joel Brobecker 2008-10-16 16:25:04 +00:00
parent 176d289d29
commit ce78b96d4f
4 changed files with 299 additions and 127 deletions

View File

@ -1,3 +1,41 @@
2008-10-16 Joel Brobecker <brobecker@adacore.com>
* breakpoint.h (enum bptype): New enum bp_catchpoint.
Delete bp_catch_fork and bp_catch_vfork.
(struct breakpoint_ops): Add new methods "insert", "remove"
and "breakpoint_hit".
* breakpoint.c (create_fork_vfork_event_catchpoint)
(create_fork_event_catchpoint, create_vfork_event_catchpoint): Remove.
(insert_catchpoint): Remove handling of bp_catch_fork and
bp_catch_vfork catchpoints, and handle them as bp_catchpoint
catchpoints instead.
(insert_bp_location, update_breakpoints_after_exec)
(remove_breakpoint, bpstat_check_location, bpstat_what)
(allocate_bp_location): Likewise.
(print_it_typical, print_one_breakpoint_location, mention): Remove
handling of bp_catch_fork and bp_catch_vfork breakpoints.
(ep_is_catchpoint, user_settable_breakpoint)
(breakpoint_address_is_meaningful, adjust_breakpoint_address)
(breakpoint_re_set_one, disable_command, enable_command):
Remove use of bp_catch_fork and bp_catch_vfork. Add handling of
bp_catchpoint breakpoints.
(insert_catch_fork, remove_catch_fork, breakpoint_hit_catch_fork)
(print_it_catch_fork, print_one_catch_fork, print_mention_catch_fork):
New functions.
(catch_fork_breakpoint_ops): New static constant.
(insert_catch_vfork, remove_catch_vfork, breakpoint_hit_catch_vfork)
(print_it_catch_vfork, print_one_catch_vfork)
(print_mention_catch_vfork): New functions.
(catch_vfork_breakpoint_ops): New static constant.
(create_catchpoint, create_fork_vfork_event_catchpoint): New functions.
(catch_fork_command_1): Use create_fork_vfork_event_catchpoint
to create the fork and vfork catchpoints.
(gnu_v3_exception_catchpoint_ops): Set new breakpoint_ops fields.
* ada-lang.c (catch_exception_breakpoint_ops): Set new breakpoint_ops
fields.
(catch_exception_unhandled_breakpoint_ops): Likewise.
(catch_assert_breakpoint_ops): Likewise.
2008-10-16 Pedro Alves <pedro@codesourcery.com> 2008-10-16 Pedro Alves <pedro@codesourcery.com>
* remote.c (set_general_process): New. * remote.c (set_general_process): New.

View File

@ -10152,6 +10152,9 @@ print_mention_catch_exception (struct breakpoint *b)
static struct breakpoint_ops catch_exception_breakpoint_ops = static struct breakpoint_ops catch_exception_breakpoint_ops =
{ {
NULL, /* insert */
NULL, /* remove */
NULL, /* breakpoint_hit */
print_it_catch_exception, print_it_catch_exception,
print_one_catch_exception, print_one_catch_exception,
print_mention_catch_exception print_mention_catch_exception
@ -10178,6 +10181,9 @@ print_mention_catch_exception_unhandled (struct breakpoint *b)
} }
static struct breakpoint_ops catch_exception_unhandled_breakpoint_ops = { static struct breakpoint_ops catch_exception_unhandled_breakpoint_ops = {
NULL, /* insert */
NULL, /* remove */
NULL, /* breakpoint_hit */
print_it_catch_exception_unhandled, print_it_catch_exception_unhandled,
print_one_catch_exception_unhandled, print_one_catch_exception_unhandled,
print_mention_catch_exception_unhandled print_mention_catch_exception_unhandled
@ -10204,6 +10210,9 @@ print_mention_catch_assert (struct breakpoint *b)
} }
static struct breakpoint_ops catch_assert_breakpoint_ops = { static struct breakpoint_ops catch_assert_breakpoint_ops = {
NULL, /* insert */
NULL, /* remove */
NULL, /* breakpoint_hit */
print_it_catch_assert, print_it_catch_assert,
print_one_catch_assert, print_one_catch_assert,
print_mention_catch_assert print_mention_catch_assert

View File

@ -159,10 +159,6 @@ static void awatch_command (char *, int);
static void do_enable_breakpoint (struct breakpoint *, enum bpdisp); static void do_enable_breakpoint (struct breakpoint *, enum bpdisp);
static void create_fork_vfork_event_catchpoint (int tempflag,
char *cond_string,
enum bptype bp_kind);
static void stop_command (char *arg, int from_tty); static void stop_command (char *arg, int from_tty);
static void stopin_command (char *arg, int from_tty); static void stopin_command (char *arg, int from_tty);
@ -797,11 +793,9 @@ insert_catchpoint (struct ui_out *uo, void *args)
switch (b->type) switch (b->type)
{ {
case bp_catch_fork: case bp_catchpoint:
target_insert_fork_catchpoint (PIDGET (inferior_ptid)); gdb_assert (b->ops != NULL && b->ops->insert != NULL);
break; b->ops->insert (b);
case bp_catch_vfork:
target_insert_vfork_catchpoint (PIDGET (inferior_ptid));
break; break;
case bp_catch_exec: case bp_catch_exec:
target_insert_exec_catchpoint (PIDGET (inferior_ptid)); target_insert_exec_catchpoint (PIDGET (inferior_ptid));
@ -1244,8 +1238,7 @@ Note: automatically using hardware breakpoints for read-only addresses.\n"));
bpt->inserted = (val != -1); bpt->inserted = (val != -1);
} }
else if (bpt->owner->type == bp_catch_fork else if (bpt->owner->type == bp_catchpoint
|| bpt->owner->type == bp_catch_vfork
|| bpt->owner->type == bp_catch_exec) || bpt->owner->type == bp_catch_exec)
{ {
struct gdb_exception e = catch_exception (uiout, insert_catchpoint, struct gdb_exception e = catch_exception (uiout, insert_catchpoint,
@ -1501,17 +1494,18 @@ update_breakpoints_after_exec (void)
continue; continue;
} }
/* Don't delete an exec catchpoint, because else the inferior if (b->type == bp_catchpoint)
won't stop when it ought! {
/* For now, none of the bp_catchpoint breakpoints need to
do anything at this point. In the future, if some of
the catchpoints need to something, we will need to add
a new method, and call this method from here. */
continue;
}
Similarly, we probably ought to keep vfork catchpoints, 'cause /* Don't delete an exec catchpoint, because else the inferior
on this target, we may not be able to stop when the vfork is won't stop when it ought! */
seen, but only when the subsequent exec is seen. (And because if (b->type == bp_catch_exec)
deleting fork catchpoints here but not vfork catchpoints will
seem mysterious to users, keep those too.) */
if ((b->type == bp_catch_exec) ||
(b->type == bp_catch_vfork) ||
(b->type == bp_catch_fork))
{ {
continue; continue;
} }
@ -1686,21 +1680,24 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is)
warning (_("Could not remove hardware watchpoint %d."), warning (_("Could not remove hardware watchpoint %d."),
b->owner->number); b->owner->number);
} }
else if ((b->owner->type == bp_catch_fork || else if (b->owner->type == bp_catchpoint
b->owner->type == bp_catch_vfork || && breakpoint_enabled (b->owner)
b->owner->type == bp_catch_exec) && !b->duplicate)
{
gdb_assert (b->owner->ops != NULL && b->owner->ops->remove != NULL);
val = b->owner->ops->remove (b->owner);
if (val)
return val;
b->inserted = (is == mark_inserted);
}
else if (b->owner->type == bp_catch_exec
&& breakpoint_enabled (b->owner) && breakpoint_enabled (b->owner)
&& !b->duplicate) && !b->duplicate)
{ {
val = -1; val = -1;
switch (b->owner->type) switch (b->owner->type)
{ {
case bp_catch_fork:
val = target_remove_fork_catchpoint (PIDGET (inferior_ptid));
break;
case bp_catch_vfork:
val = target_remove_vfork_catchpoint (PIDGET (inferior_ptid));
break;
case bp_catch_exec: case bp_catch_exec:
val = target_remove_exec_catchpoint (PIDGET (inferior_ptid)); val = target_remove_exec_catchpoint (PIDGET (inferior_ptid));
break; break;
@ -1968,11 +1965,9 @@ breakpoint_thread_match (CORE_ADDR pc, ptid_t ptid)
int int
ep_is_catchpoint (struct breakpoint *ep) ep_is_catchpoint (struct breakpoint *ep)
{ {
return return (ep->type == bp_catchpoint)
(ep->type == bp_catch_load) || (ep->type == bp_catch_load)
|| (ep->type == bp_catch_unload) || (ep->type == bp_catch_unload)
|| (ep->type == bp_catch_fork)
|| (ep->type == bp_catch_vfork)
|| (ep->type == bp_catch_exec); || (ep->type == bp_catch_exec);
/* ??rehrauer: Add more kinds here, as are implemented... */ /* ??rehrauer: Add more kinds here, as are implemented... */
@ -2367,22 +2362,6 @@ print_it_typical (bpstat bs)
return PRINT_SRC_AND_LOC; return PRINT_SRC_AND_LOC;
break; break;
case bp_catch_fork:
annotate_catchpoint (b->number);
printf_filtered (_("\nCatchpoint %d (forked process %d), "),
b->number,
ptid_get_pid (b->forked_inferior_pid));
return PRINT_SRC_AND_LOC;
break;
case bp_catch_vfork:
annotate_catchpoint (b->number);
printf_filtered (_("\nCatchpoint %d (vforked process %d), "),
b->number,
ptid_get_pid (b->forked_inferior_pid));
return PRINT_SRC_AND_LOC;
break;
case bp_catch_exec: case bp_catch_exec:
annotate_catchpoint (b->number); annotate_catchpoint (b->number);
printf_filtered (_("\nCatchpoint %d (exec'd %s), "), printf_filtered (_("\nCatchpoint %d (exec'd %s), "),
@ -2809,8 +2788,7 @@ bpstat_check_location (const struct bp_location *bl, CORE_ADDR bp_addr)
&& b->type != bp_read_watchpoint && b->type != bp_read_watchpoint
&& b->type != bp_access_watchpoint && b->type != bp_access_watchpoint
&& b->type != bp_hardware_breakpoint && b->type != bp_hardware_breakpoint
&& b->type != bp_catch_fork && b->type != bp_catchpoint
&& b->type != bp_catch_vfork
&& b->type != bp_catch_exec) /* a non-watchpoint bp */ && b->type != bp_catch_exec) /* a non-watchpoint bp */
{ {
if (bl->address != bp_addr) /* address doesn't match */ if (bl->address != bp_addr) /* address doesn't match */
@ -2871,15 +2849,12 @@ bpstat_check_location (const struct bp_location *bl, CORE_ADDR bp_addr)
) )
return 0; return 0;
if ((b->type == bp_catch_fork) if (b->type == bp_catchpoint)
&& !inferior_has_forked (inferior_ptid, {
&b->forked_inferior_pid)) gdb_assert (b->ops != NULL && b->ops->breakpoint_hit != NULL);
return 0; if (!b->ops->breakpoint_hit (b))
if ((b->type == bp_catch_vfork)
&& !inferior_has_vforked (inferior_ptid,
&b->forked_inferior_pid))
return 0; return 0;
}
if ((b->type == bp_catch_exec) if ((b->type == bp_catch_exec)
&& !inferior_has_execd (inferior_ptid, &b->exec_pathname)) && !inferior_has_execd (inferior_ptid, &b->exec_pathname))
@ -3409,8 +3384,7 @@ bpstat_what (bpstat bs)
else else
bs_class = no_effect; bs_class = no_effect;
break; break;
case bp_catch_fork: case bp_catchpoint:
case bp_catch_vfork:
case bp_catch_exec: case bp_catch_exec:
if (bs->stop) if (bs->stop)
{ {
@ -3589,10 +3563,9 @@ print_one_breakpoint_location (struct breakpoint *b,
{bp_shlib_event, "shlib events"}, {bp_shlib_event, "shlib events"},
{bp_thread_event, "thread events"}, {bp_thread_event, "thread events"},
{bp_overlay_event, "overlay events"}, {bp_overlay_event, "overlay events"},
{bp_catchpoint, "catchpoint"},
{bp_catch_load, "catch load"}, {bp_catch_load, "catch load"},
{bp_catch_unload, "catch unload"}, {bp_catch_unload, "catch unload"},
{bp_catch_fork, "catch fork"},
{bp_catch_vfork, "catch vfork"},
{bp_catch_exec, "catch exec"} {bp_catch_exec, "catch exec"}
}; };
@ -3727,23 +3700,6 @@ print_one_breakpoint_location (struct breakpoint *b,
} }
break; break;
case bp_catch_fork:
case bp_catch_vfork:
/* 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 (addressprint)
ui_out_field_skip (uiout, "addr");
annotate_field (5);
if (!ptid_equal (b->forked_inferior_pid, null_ptid))
{
ui_out_text (uiout, "process ");
ui_out_field_int (uiout, "what",
ptid_get_pid (b->forked_inferior_pid));
ui_out_spaces (uiout, 1);
}
break;
case bp_catch_exec: case bp_catch_exec:
/* Field 4, the address, is omitted (which makes the columns /* Field 4, the address, is omitted (which makes the columns
not line up too nicely with the headers, but the effect not line up too nicely with the headers, but the effect
@ -3955,10 +3911,9 @@ static int
user_settable_breakpoint (const struct breakpoint *b) user_settable_breakpoint (const struct breakpoint *b)
{ {
return (b->type == bp_breakpoint return (b->type == bp_breakpoint
|| b->type == bp_catchpoint
|| b->type == bp_catch_load || b->type == bp_catch_load
|| b->type == bp_catch_unload || b->type == bp_catch_unload
|| b->type == bp_catch_fork
|| b->type == bp_catch_vfork
|| b->type == bp_catch_exec || b->type == bp_catch_exec
|| b->type == bp_hardware_breakpoint || b->type == bp_hardware_breakpoint
|| b->type == bp_watchpoint || b->type == bp_watchpoint
@ -4166,9 +4121,8 @@ set_default_breakpoint (int valid, CORE_ADDR addr, struct symtab *symtab,
bp_hardware_watchpoint bp_hardware_watchpoint
bp_read_watchpoint bp_read_watchpoint
bp_access_watchpoint bp_access_watchpoint
bp_catch_exec bp_catchpoint
bp_catch_fork bp_catch_exec */
bp_catch_vork */
static int static int
breakpoint_address_is_meaningful (struct breakpoint *bpt) breakpoint_address_is_meaningful (struct breakpoint *bpt)
@ -4179,9 +4133,8 @@ breakpoint_address_is_meaningful (struct breakpoint *bpt)
&& type != bp_hardware_watchpoint && type != bp_hardware_watchpoint
&& type != bp_read_watchpoint && type != bp_read_watchpoint
&& type != bp_access_watchpoint && type != bp_access_watchpoint
&& type != bp_catch_exec && type != bp_catchpoint
&& type != bp_catch_fork && type != bp_catch_exec);
&& type != bp_catch_vfork);
} }
/* Rescan breakpoints at the same address and section as BPT, /* Rescan breakpoints at the same address and section as BPT,
@ -4296,8 +4249,7 @@ adjust_breakpoint_address (CORE_ADDR bpaddr, enum bptype bptype)
|| bptype == bp_hardware_watchpoint || bptype == bp_hardware_watchpoint
|| bptype == bp_read_watchpoint || bptype == bp_read_watchpoint
|| bptype == bp_access_watchpoint || bptype == bp_access_watchpoint
|| bptype == bp_catch_fork || bptype == bp_catchpoint
|| bptype == bp_catch_vfork
|| bptype == bp_catch_exec) || bptype == bp_catch_exec)
{ {
/* Watchpoints and the various bp_catch_* eventpoints should not /* Watchpoints and the various bp_catch_* eventpoints should not
@ -4364,8 +4316,7 @@ allocate_bp_location (struct breakpoint *bpt, enum bptype bp_type)
loc->loc_type = bp_loc_hardware_watchpoint; loc->loc_type = bp_loc_hardware_watchpoint;
break; break;
case bp_watchpoint: case bp_watchpoint:
case bp_catch_fork: case bp_catchpoint:
case bp_catch_vfork:
case bp_catch_exec: case bp_catch_exec:
loc->loc_type = bp_loc_other; loc->loc_type = bp_loc_other;
break; break;
@ -4766,45 +4717,210 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
} }
} }
/* FORK & VFORK catchpoints. */
/* Implement the "insert" breakpoint_ops method for fork catchpoints. */
static void static void
create_fork_vfork_event_catchpoint (int tempflag, char *cond_string, insert_catch_fork (struct breakpoint *b)
enum bptype bp_kind) {
target_insert_fork_catchpoint (PIDGET (inferior_ptid));
}
/* Implement the "remove" breakpoint_ops method for fork catchpoints. */
static int
remove_catch_fork (struct breakpoint *b)
{
return target_remove_fork_catchpoint (PIDGET (inferior_ptid));
}
/* Implement the "breakpoint_hit" breakpoint_ops method for fork
catchpoints. */
static int
breakpoint_hit_catch_fork (struct breakpoint *b)
{
return inferior_has_forked (inferior_ptid, &b->forked_inferior_pid);
}
/* Implement the "print_it" breakpoint_ops method for fork catchpoints. */
static enum print_stop_action
print_it_catch_fork (struct breakpoint *b)
{
annotate_catchpoint (b->number);
printf_filtered (_("\nCatchpoint %d (forked process %d), "),
b->number, ptid_get_pid (b->forked_inferior_pid));
return PRINT_SRC_AND_LOC;
}
/* Implement the "print_one" breakpoint_ops method for fork catchpoints. */
static void
print_one_catch_fork (struct breakpoint *b, CORE_ADDR *last_addr)
{
/* 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 (addressprint)
ui_out_field_skip (uiout, "addr");
annotate_field (5);
ui_out_text (uiout, "fork");
if (!ptid_equal (b->forked_inferior_pid, null_ptid))
{
ui_out_text (uiout, ", process ");
ui_out_field_int (uiout, "what",
ptid_get_pid (b->forked_inferior_pid));
ui_out_spaces (uiout, 1);
}
}
/* Implement the "print_mention" breakpoint_ops method for fork
catchpoints. */
static void
print_mention_catch_fork (struct breakpoint *b)
{
printf_filtered (_("Catchpoint %d (fork)"), b->number);
}
/* The breakpoint_ops structure to be used in fork catchpoints. */
static struct breakpoint_ops catch_fork_breakpoint_ops =
{
insert_catch_fork,
remove_catch_fork,
breakpoint_hit_catch_fork,
print_it_catch_fork,
print_one_catch_fork,
print_mention_catch_fork
};
/* Implement the "insert" breakpoint_ops method for vfork catchpoints. */
static void
insert_catch_vfork (struct breakpoint *b)
{
target_insert_vfork_catchpoint (PIDGET (inferior_ptid));
}
/* Implement the "remove" breakpoint_ops method for vfork catchpoints. */
static int
remove_catch_vfork (struct breakpoint *b)
{
return target_remove_vfork_catchpoint (PIDGET (inferior_ptid));
}
/* Implement the "breakpoint_hit" breakpoint_ops method for vfork
catchpoints. */
static int
breakpoint_hit_catch_vfork (struct breakpoint *b)
{
return inferior_has_vforked (inferior_ptid, &b->forked_inferior_pid);
}
/* Implement the "print_it" breakpoint_ops method for vfork catchpoints. */
static enum print_stop_action
print_it_catch_vfork (struct breakpoint *b)
{
annotate_catchpoint (b->number);
printf_filtered (_("\nCatchpoint %d (vforked process %d), "),
b->number, ptid_get_pid (b->forked_inferior_pid));
return PRINT_SRC_AND_LOC;
}
/* Implement the "print_one" breakpoint_ops method for vfork catchpoints. */
static void
print_one_catch_vfork (struct breakpoint *b, CORE_ADDR *last_addr)
{
/* 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 (addressprint)
ui_out_field_skip (uiout, "addr");
annotate_field (5);
ui_out_text (uiout, "vfork");
if (!ptid_equal (b->forked_inferior_pid, null_ptid))
{
ui_out_text (uiout, ", process ");
ui_out_field_int (uiout, "what",
ptid_get_pid (b->forked_inferior_pid));
ui_out_spaces (uiout, 1);
}
}
/* Implement the "print_mention" breakpoint_ops method for vfork
catchpoints. */
static void
print_mention_catch_vfork (struct breakpoint *b)
{
printf_filtered (_("Catchpoint %d (vfork)"), b->number);
}
/* The breakpoint_ops structure to be used in vfork catchpoints. */
static struct breakpoint_ops catch_vfork_breakpoint_ops =
{
insert_catch_vfork,
remove_catch_vfork,
breakpoint_hit_catch_vfork,
print_it_catch_vfork,
print_one_catch_vfork,
print_mention_catch_vfork
};
/* 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. */
static struct breakpoint *
create_catchpoint (int tempflag, char *cond_string,
struct breakpoint_ops *ops)
{ {
struct symtab_and_line sal; struct symtab_and_line sal;
struct breakpoint *b; struct breakpoint *b;
int thread = -1; /* All threads. */
init_sal (&sal); init_sal (&sal);
sal.pc = 0; sal.pc = 0;
sal.symtab = NULL; sal.symtab = NULL;
sal.line = 0; sal.line = 0;
b = set_raw_breakpoint (sal, bp_kind); b = set_raw_breakpoint (sal, bp_catchpoint);
set_breakpoint_count (breakpoint_count + 1); set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count; b->number = breakpoint_count;
b->cond_string = (cond_string == NULL) ? b->cond_string = (cond_string == NULL) ?
NULL : savestring (cond_string, strlen (cond_string)); NULL : savestring (cond_string, strlen (cond_string));
b->thread = thread; b->thread = -1;
b->addr_string = NULL; b->addr_string = NULL;
b->enable_state = bp_enabled; b->enable_state = bp_enabled;
b->disposition = tempflag ? disp_del : disp_donttouch; b->disposition = tempflag ? disp_del : disp_donttouch;
b->forked_inferior_pid = null_ptid; b->ops = ops;
update_global_location_list (1);
mention (b); mention (b);
update_global_location_list (1);
return b;
} }
static void static void
create_fork_event_catchpoint (int tempflag, char *cond_string) create_fork_vfork_event_catchpoint (int tempflag, char *cond_string,
struct breakpoint_ops *ops)
{ {
create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_fork); struct breakpoint *b = create_catchpoint (tempflag, cond_string, ops);
}
static void /* FIXME: We should put this information in a breakpoint private data
create_vfork_event_catchpoint (int tempflag, char *cond_string) area. */
{ b->forked_inferior_pid = null_ptid;
create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_vfork);
} }
static void static void
@ -5040,12 +5156,6 @@ mention (struct breakpoint *b)
(b->dll_pathname != NULL) ? (b->dll_pathname != NULL) ?
b->dll_pathname : "<any library>"); b->dll_pathname : "<any library>");
break; break;
case bp_catch_fork:
case bp_catch_vfork:
printf_filtered (_("Catchpoint %d (%s)"),
b->number,
(b->type == bp_catch_fork) ? "fork" : "vfork");
break;
case bp_catch_exec: case bp_catch_exec:
printf_filtered (_("Catchpoint %d (exec)"), printf_filtered (_("Catchpoint %d (exec)"),
b->number); b->number);
@ -6466,11 +6576,13 @@ catch_fork_command_1 (char *arg, int from_tty, struct cmd_list_element *command)
{ {
case catch_fork_temporary: case catch_fork_temporary:
case catch_fork_permanent: case catch_fork_permanent:
create_fork_event_catchpoint (tempflag, cond_string); create_fork_vfork_event_catchpoint (tempflag, cond_string,
&catch_fork_breakpoint_ops);
break; break;
case catch_vfork_temporary: case catch_vfork_temporary:
case catch_vfork_permanent: case catch_vfork_permanent:
create_vfork_event_catchpoint (tempflag, cond_string); create_fork_vfork_event_catchpoint (tempflag, cond_string,
&catch_vfork_breakpoint_ops);
break; break;
default: default:
error (_("unsupported or unknown fork kind; cannot catch it")); error (_("unsupported or unknown fork kind; cannot catch it"));
@ -6667,6 +6779,9 @@ print_mention_exception_catchpoint (struct breakpoint *b)
} }
static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = { static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = {
NULL, /* insert */
NULL, /* remove */
NULL, /* breakpoint_hit */
print_exception_catchpoint, print_exception_catchpoint,
print_one_exception_catchpoint, print_one_exception_catchpoint,
print_mention_exception_catchpoint print_mention_exception_catchpoint
@ -7635,8 +7750,7 @@ breakpoint_re_set_one (void *bint)
/* We needn't really do anything to reset these, since the mask /* We needn't really do anything to reset these, since the mask
that requests them is unaffected by e.g., new libraries being that requests them is unaffected by e.g., new libraries being
loaded. */ loaded. */
case bp_catch_fork: case bp_catchpoint:
case bp_catch_vfork:
case bp_catch_exec: case bp_catch_exec:
break; break;
@ -7896,10 +8010,9 @@ disable_command (char *args, int from_tty)
bpt->number); bpt->number);
continue; continue;
case bp_breakpoint: case bp_breakpoint:
case bp_catchpoint:
case bp_catch_load: case bp_catch_load:
case bp_catch_unload: case bp_catch_unload:
case bp_catch_fork:
case bp_catch_vfork:
case bp_catch_exec: case bp_catch_exec:
case bp_hardware_breakpoint: case bp_hardware_breakpoint:
case bp_watchpoint: case bp_watchpoint:
@ -8030,10 +8143,9 @@ enable_command (char *args, int from_tty)
bpt->number); bpt->number);
continue; continue;
case bp_breakpoint: case bp_breakpoint:
case bp_catchpoint:
case bp_catch_load: case bp_catch_load:
case bp_catch_unload: case bp_catch_unload:
case bp_catch_fork:
case bp_catch_vfork:
case bp_catch_exec: case bp_catch_exec:
case bp_hardware_breakpoint: case bp_hardware_breakpoint:
case bp_watchpoint: case bp_watchpoint:

View File

@ -110,6 +110,8 @@ enum bptype
bp_overlay_event, bp_overlay_event,
bp_catchpoint,
/* These breakpoints are used to implement the "catch load" command /* These breakpoints are used to implement the "catch load" command
on platforms whose dynamic linkers support such functionality. */ on platforms whose dynamic linkers support such functionality. */
bp_catch_load, bp_catch_load,
@ -124,8 +126,6 @@ enum bptype
kernels which can raise an event when a fork or exec occurs, as kernels which can raise an event when a fork or exec occurs, as
opposed to the debugger setting breakpoints on functions named opposed to the debugger setting breakpoints on functions named
"fork" or "exec".) */ "fork" or "exec".) */
bp_catch_fork,
bp_catch_vfork,
bp_catch_exec, bp_catch_exec,
}; };
@ -315,6 +315,19 @@ struct bp_location
struct breakpoint_ops struct breakpoint_ops
{ {
/* Insert the breakpoint or activate the catchpoint. Should raise
an exception if the operation failed. */
void (*insert) (struct breakpoint *);
/* Remove the breakpoint/catchpoint that was previously inserted
with the "insert" method above. Return non-zero if the operation
succeeded. */
int (*remove) (struct breakpoint *);
/* Return non-zero if the debugger should tell the user that this
breakpoint was hit. */
int (*breakpoint_hit) (struct breakpoint *);
/* The normal print routine for this breakpoint, called when we /* The normal print routine for this breakpoint, called when we
hit it. */ hit it. */
enum print_stop_action (*print_it) (struct breakpoint *); enum print_stop_action (*print_it) (struct breakpoint *);