Index: breakpoint.h =================================================================== RCS file: /cvs/src/src/gdb/breakpoint.h,v retrieving revision 1.80 diff -u -p -r1.80 breakpoint.h --- breakpoint.h 14 Oct 2008 20:49:02 -0000 1.80 +++ breakpoint.h 15 Oct 2008 04:33:21 -0000 @@ -110,6 +110,8 @@ enum bptype bp_overlay_event, + bp_catchpoint, + /* These breakpoints are used to implement the "catch load" command on platforms whose dynamic linkers support such functionality. */ bp_catch_load, @@ -124,8 +126,6 @@ enum bptype kernels which can raise an event when a fork or exec occurs, as opposed to the debugger setting breakpoints on functions named "fork" or "exec".) */ - bp_catch_fork, - bp_catch_vfork, bp_catch_exec, }; @@ -315,6 +315,19 @@ struct bp_location 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 hit it. */ enum print_stop_action (*print_it) (struct breakpoint *); Index: breakpoint.c =================================================================== RCS file: /cvs/src/src/gdb/breakpoint.c,v retrieving revision 1.353 diff -u -p -r1.353 breakpoint.c --- breakpoint.c 14 Oct 2008 20:49:02 -0000 1.353 +++ breakpoint.c 15 Oct 2008 04:33:24 -0000 @@ -159,10 +159,6 @@ static void awatch_command (char *, int) 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 stopin_command (char *arg, int from_tty); @@ -797,11 +793,9 @@ insert_catchpoint (struct ui_out *uo, vo switch (b->type) { - case bp_catch_fork: - target_insert_fork_catchpoint (PIDGET (inferior_ptid)); - break; - case bp_catch_vfork: - target_insert_vfork_catchpoint (PIDGET (inferior_ptid)); + case bp_catchpoint: + gdb_assert (b->ops != NULL && b->ops->insert != NULL); + b->ops->insert (b); break; case bp_catch_exec: target_insert_exec_catchpoint (PIDGET (inferior_ptid)); @@ -1244,8 +1238,7 @@ Note: automatically using hardware break bpt->inserted = (val != -1); } - else if (bpt->owner->type == bp_catch_fork - || bpt->owner->type == bp_catch_vfork + else if (bpt->owner->type == bp_catchpoint || bpt->owner->type == bp_catch_exec) { struct gdb_exception e = catch_exception (uiout, insert_catchpoint, @@ -1501,17 +1494,18 @@ update_breakpoints_after_exec (void) continue; } - /* Don't delete an exec catchpoint, because else the inferior - won't stop when it ought! + if (b->type == bp_catchpoint) + { + /* 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 - on this target, we may not be able to stop when the vfork is - seen, but only when the subsequent exec is seen. (And because - 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)) + /* Don't delete an exec catchpoint, because else the inferior + won't stop when it ought! */ + if (b->type == bp_catch_exec) { continue; } @@ -1686,21 +1680,24 @@ remove_breakpoint (struct bp_location *b warning (_("Could not remove hardware watchpoint %d."), b->owner->number); } - else if ((b->owner->type == bp_catch_fork || - b->owner->type == bp_catch_vfork || - b->owner->type == bp_catch_exec) + else if (b->owner->type == bp_catchpoint + && breakpoint_enabled (b->owner) + && !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) && !b->duplicate) { val = -1; 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: val = target_remove_exec_catchpoint (PIDGET (inferior_ptid)); break; @@ -1948,11 +1945,9 @@ breakpoint_thread_match (CORE_ADDR pc, p int ep_is_catchpoint (struct breakpoint *ep) { - return - (ep->type == bp_catch_load) + return (ep->type == bp_catchpoint) + || (ep->type == bp_catch_load) || (ep->type == bp_catch_unload) - || (ep->type == bp_catch_fork) - || (ep->type == bp_catch_vfork) || (ep->type == bp_catch_exec); /* ??rehrauer: Add more kinds here, as are implemented... */ @@ -2347,22 +2342,6 @@ print_it_typical (bpstat bs) return PRINT_SRC_AND_LOC; 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: annotate_catchpoint (b->number); printf_filtered (_("\nCatchpoint %d (exec'd %s), "), @@ -2789,8 +2768,7 @@ bpstat_check_location (const struct bp_l && b->type != bp_read_watchpoint && b->type != bp_access_watchpoint && b->type != bp_hardware_breakpoint - && b->type != bp_catch_fork - && b->type != bp_catch_vfork + && b->type != bp_catchpoint && b->type != bp_catch_exec) /* a non-watchpoint bp */ { if (bl->address != bp_addr) /* address doesn't match */ @@ -2823,7 +2801,7 @@ bpstat_check_location (const struct bp_l && !section_is_mapped (bl->section)) return 0; } - + /* Is this a catchpoint of a load or unload? If so, did we get a load or unload of the specified library? If not, ignore it. */ @@ -2851,16 +2829,13 @@ bpstat_check_location (const struct bp_l ) return 0; - if ((b->type == bp_catch_fork) - && !inferior_has_forked (inferior_ptid, - &b->forked_inferior_pid)) - return 0; - - if ((b->type == bp_catch_vfork) - && !inferior_has_vforked (inferior_ptid, - &b->forked_inferior_pid)) - return 0; - + if (b->type == bp_catchpoint) + { + gdb_assert (b->ops != NULL && b->ops->breakpoint_hit != NULL); + if (!b->ops->breakpoint_hit (b)) + return 0; + } + if ((b->type == bp_catch_exec) && !inferior_has_execd (inferior_ptid, &b->exec_pathname)) return 0; @@ -3389,8 +3364,7 @@ bpstat_what (bpstat bs) else bs_class = no_effect; break; - case bp_catch_fork: - case bp_catch_vfork: + case bp_catchpoint: case bp_catch_exec: if (bs->stop) { @@ -3569,10 +3543,9 @@ print_one_breakpoint_location (struct br {bp_shlib_event, "shlib events"}, {bp_thread_event, "thread events"}, {bp_overlay_event, "overlay events"}, + {bp_catchpoint, "catchpoint"}, {bp_catch_load, "catch load"}, {bp_catch_unload, "catch unload"}, - {bp_catch_fork, "catch fork"}, - {bp_catch_vfork, "catch vfork"}, {bp_catch_exec, "catch exec"} }; @@ -3707,23 +3680,6 @@ print_one_breakpoint_location (struct br } 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: /* Field 4, the address, is omitted (which makes the columns not line up too nicely with the headers, but the effect @@ -3935,10 +3891,9 @@ static int user_settable_breakpoint (const struct breakpoint *b) { return (b->type == bp_breakpoint + || b->type == bp_catchpoint || b->type == bp_catch_load || b->type == bp_catch_unload - || b->type == bp_catch_fork - || b->type == bp_catch_vfork || b->type == bp_catch_exec || b->type == bp_hardware_breakpoint || b->type == bp_watchpoint @@ -4146,9 +4101,8 @@ set_default_breakpoint (int valid, CORE_ bp_hardware_watchpoint bp_read_watchpoint bp_access_watchpoint - bp_catch_exec - bp_catch_fork - bp_catch_vork */ + bp_catchpoint + bp_catch_exec */ static int breakpoint_address_is_meaningful (struct breakpoint *bpt) @@ -4159,9 +4113,8 @@ breakpoint_address_is_meaningful (struct && type != bp_hardware_watchpoint && type != bp_read_watchpoint && type != bp_access_watchpoint - && type != bp_catch_exec - && type != bp_catch_fork - && type != bp_catch_vfork); + && type != bp_catchpoint + && type != bp_catch_exec); } /* Rescan breakpoints at the same address and section as BPT, @@ -4276,8 +4229,7 @@ adjust_breakpoint_address (CORE_ADDR bpa || bptype == bp_hardware_watchpoint || bptype == bp_read_watchpoint || bptype == bp_access_watchpoint - || bptype == bp_catch_fork - || bptype == bp_catch_vfork + || bptype == bp_catchpoint || bptype == bp_catch_exec) { /* Watchpoints and the various bp_catch_* eventpoints should not @@ -4344,8 +4296,7 @@ allocate_bp_location (struct breakpoint loc->loc_type = bp_loc_hardware_watchpoint; break; case bp_watchpoint: - case bp_catch_fork: - case bp_catch_vfork: + case bp_catchpoint: case bp_catch_exec: loc->loc_type = bp_loc_other; break; @@ -4746,45 +4697,210 @@ disable_breakpoints_in_unloaded_shlib (s } } +/* FORK & VFORK catchpoints. */ + +/* Implement the "insert" breakpoint_ops method for fork catchpoints. */ + static void -create_fork_vfork_event_catchpoint (int tempflag, char *cond_string, - enum bptype bp_kind) +insert_catch_fork (struct breakpoint *b) +{ + 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 breakpoint *b; - int thread = -1; /* All threads. */ init_sal (&sal); sal.pc = 0; sal.symtab = NULL; sal.line = 0; - b = set_raw_breakpoint (sal, bp_kind); + b = set_raw_breakpoint (sal, bp_catchpoint); set_breakpoint_count (breakpoint_count + 1); b->number = breakpoint_count; + b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string)); - b->thread = thread; + b->thread = -1; b->addr_string = NULL; b->enable_state = bp_enabled; b->disposition = tempflag ? disp_del : disp_donttouch; - b->forked_inferior_pid = null_ptid; - update_global_location_list (1); - + b->ops = ops; mention (b); -} + update_global_location_list (1); -static void -create_fork_event_catchpoint (int tempflag, char *cond_string) -{ - create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_fork); + return b; } static void -create_vfork_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_vfork); + struct breakpoint *b = create_catchpoint (tempflag, cond_string, ops); + + /* FIXME: We should put this information in a breakpoint private data + area. */ + b->forked_inferior_pid = null_ptid; } static void @@ -5020,12 +5136,6 @@ mention (struct breakpoint *b) (b->dll_pathname != NULL) ? b->dll_pathname : ""); 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: printf_filtered (_("Catchpoint %d (exec)"), b->number); @@ -6446,11 +6556,13 @@ catch_fork_command_1 (char *arg, int fro { case catch_fork_temporary: case catch_fork_permanent: - create_fork_event_catchpoint (tempflag, cond_string); + create_fork_vfork_event_catchpoint (tempflag, cond_string, + &catch_fork_breakpoint_ops); break; case catch_vfork_temporary: case catch_vfork_permanent: - create_vfork_event_catchpoint (tempflag, cond_string); + create_fork_vfork_event_catchpoint (tempflag, cond_string, + &catch_vfork_breakpoint_ops); break; default: error (_("unsupported or unknown fork kind; cannot catch it")); @@ -6647,6 +6759,9 @@ print_mention_exception_catchpoint (stru } static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = { + NULL, /* insert */ + NULL, /* remove */ + NULL, /* breakpoint_hit */ print_exception_catchpoint, print_one_exception_catchpoint, print_mention_exception_catchpoint @@ -7613,8 +7728,7 @@ breakpoint_re_set_one (void *bint) /* We needn't really do anything to reset these, since the mask that requests them is unaffected by e.g., new libraries being loaded. */ - case bp_catch_fork: - case bp_catch_vfork: + case bp_catchpoint: case bp_catch_exec: break; @@ -7874,10 +7988,9 @@ disable_command (char *args, int from_tt bpt->number); continue; case bp_breakpoint: + case bp_catchpoint: case bp_catch_load: case bp_catch_unload: - case bp_catch_fork: - case bp_catch_vfork: case bp_catch_exec: case bp_hardware_breakpoint: case bp_watchpoint: @@ -8008,10 +8121,9 @@ enable_command (char *args, int from_tty bpt->number); continue; case bp_breakpoint: + case bp_catchpoint: case bp_catch_load: case bp_catch_unload: - case bp_catch_fork: - case bp_catch_vfork: case bp_catch_exec: case bp_hardware_breakpoint: case bp_watchpoint: Index: ada-lang.c =================================================================== RCS file: /cvs/src/src/gdb/ada-lang.c,v retrieving revision 1.178 diff -u -p -r1.178 ada-lang.c --- ada-lang.c 7 Oct 2008 14:07:10 -0000 1.178 +++ ada-lang.c 15 Oct 2008 04:52:30 -0000 @@ -10152,6 +10152,9 @@ print_mention_catch_exception (struct br static struct breakpoint_ops catch_exception_breakpoint_ops = { + NULL, /* insert */ + NULL, /* remove */ + NULL, /* breakpoint_hit */ print_it_catch_exception, print_one_catch_exception, print_mention_catch_exception @@ -10178,6 +10181,9 @@ print_mention_catch_exception_unhandled } static struct breakpoint_ops catch_exception_unhandled_breakpoint_ops = { + NULL, /* insert */ + NULL, /* remove */ + NULL, /* breakpoint_hit */ print_it_catch_exception_unhandled, print_one_catch_exception_unhandled, print_mention_catch_exception_unhandled @@ -10204,6 +10210,9 @@ print_mention_catch_assert (struct break } static struct breakpoint_ops catch_assert_breakpoint_ops = { + NULL, /* insert */ + NULL, /* remove */ + NULL, /* breakpoint_hit */ print_it_catch_assert, print_one_catch_assert, print_mention_catch_assert