From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30703 invoked by alias); 6 Oct 2008 17:22:22 -0000 Received: (qmail 30691 invoked by uid 22791); 6 Oct 2008 17:22:19 -0000 X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 06 Oct 2008 17:21:39 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 1C6452A963E; Mon, 6 Oct 2008 13:21:37 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 2ns0cqe+RWO8; Mon, 6 Oct 2008 13:21:37 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id E78562A95DD; Mon, 6 Oct 2008 13:21:36 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id 9100CE7ACD; Mon, 6 Oct 2008 10:21:36 -0700 (PDT) Date: Mon, 06 Oct 2008 17:22:00 -0000 From: Joel Brobecker To: =?iso-8859-1?Q?S=E9rgio_Durigan_J=FAnior?= Cc: gdb-patches@sourceware.org Subject: Re: [PATCH 1/4] 'catch syscall' feature -- Architecture-independent part Message-ID: <20081006172136.GA3588@adacore.com> References: <1222798409.30389.23.camel@miki> <20081002211256.GO3665@adacore.com> <1223001252.9858.11.camel@miki> <20081003060629.GQ3665@adacore.com> <1223161515.5956.25.camel@miki> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="oyUTqETQ0mS9luUI" Content-Disposition: inline In-Reply-To: <1223161515.5956.25.camel@miki> User-Agent: Mutt/1.4.2.2i Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-10/txt/msg00148.txt.bz2 --oyUTqETQ0mS9luUI Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 2225 > Meanwhile, I'll try to understand and improve things by my own :-). Here is a patch that converts fork/vfork catchpoints to using breakpoint_ops. I introduces 3 new "methods" for inserting/removing/ and breakpoint_hit, and should give you an idea of what the code should look like. For your feature, let's see if others agree to check it in. If it goes in, then you can leverage on the new kind. I would have gone ahead and converted exec as as well as shared-library load/unload, since it's fairly mechanical and would be a welcome cleanup, but I'm a bit short on time, and I want to continue submitting other changes we made. If this change looks ok to the others as well, I'll try to convert more during my evenings after dinner. 2008-10-06 Joel Brobecker * breakpoint.h (enum bptype): New enum bp_catchpoint. Delete bp_catch_fork and bp_catch_vfork. * breakpoint.c: Implement the catch fork/vfork feature using the bp_catchpoint bptype enum and the breakpoint_ops structure. Remove the use of bp_catch_fork and bp_catch_vfork breakpoint kinds. 2008-10-06 Joel Brobecker * gdb.base/foll-fork.exp: Adjust the expected output to match the new description for fork/vfork catchpoints in the "info breakpoints" output. Tested on x86-linux. A couple of side remarks: 1. I think it would be useful to introduce a private-data field that the bp_ops functions would access if necessary. We would be able to stuff the forked_inferior_pid in it, for instance. Not done here, to avoid mixing issues in the same patch. 2. I think it should be possible to split the fork/vfork ops out into a separate file. But the fork/vfork bp_ops use some static routines from breakpoint.c, and I don't necessarily want these routines to be exported. One solution would be to include a .c file from inside breakpoint.c. Not sure that this is very elegant either. For now, I elected to stay focused on the conversion. Just some thoughts maybe for later. OK to commit? I think on principle Daniel agreed, but the devil is often in the details... -- Joel --oyUTqETQ0mS9luUI Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="catchpoint-fork.diff" Content-length: 22440 diff -r c9da7894e8d5 gdb/ada-lang.c --- a/gdb/ada-lang.c Sun Oct 05 16:06:42 2008 -0700 +++ b/gdb/ada-lang.c Mon Oct 06 13:05:03 2008 -0400 @@ -10145,6 +10145,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 @@ -10171,6 +10174,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 @@ -10197,6 +10203,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 diff -r c9da7894e8d5 gdb/breakpoint.c --- a/gdb/breakpoint.c Sun Oct 05 16:06:42 2008 -0700 +++ b/gdb/breakpoint.c Mon Oct 06 13:05:03 2008 -0400 @@ -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); @@ -801,11 +797,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)); @@ -1248,8 +1242,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, @@ -1505,6 +1498,14 @@ update_breakpoints_after_exec (void) continue; } + 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. */ + } + /* Don't delete an exec catchpoint, because else the inferior won't stop when it ought! @@ -1513,9 +1514,7 @@ update_breakpoints_after_exec (void) 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)) + if (b->type == bp_catch_exec) { continue; } @@ -1690,21 +1689,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; @@ -1952,11 +1954,9 @@ int 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... */ @@ -2348,22 +2348,6 @@ print_it_typical (bpstat bs) printf_filtered (_("\nCatchpoint %d (unloaded %s), "), b->number, b->triggered_dll_pathname); - 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; @@ -2793,8 +2777,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 */ @@ -2827,7 +2810,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. */ @@ -2855,16 +2838,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; @@ -3393,8 +3373,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) { @@ -3573,10 +3552,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"} }; @@ -3708,23 +3686,6 @@ print_one_breakpoint_location (struct br ui_out_text (uiout, "library \""); ui_out_field_string (uiout, "what", b->dll_pathname); ui_out_text (uiout, "\" "); - } - 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; @@ -3939,10 +3900,9 @@ user_settable_breakpoint (const struct b 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 @@ -4150,8 +4110,8 @@ set_default_breakpoint (int valid, CORE_ bp_hardware_watchpoint bp_read_watchpoint bp_access_watchpoint + bp_catchpoint bp_catch_exec - bp_catch_fork bp_catch_vork */ static int @@ -4163,9 +4123,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, @@ -4280,8 +4239,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 @@ -4348,8 +4306,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; @@ -4750,45 +4707,210 @@ disable_breakpoints_in_unloaded_shlib (s } } -static void -create_fork_vfork_event_catchpoint (int tempflag, char *cond_string, - enum bptype bp_kind) -{ - struct symtab_and_line sal; - struct breakpoint *b; - int thread = -1; /* All threads. */ +/* FORK & VFORK catchpoints. */ + +/* Implement the "insert" breakpoint_ops method for fork catchpoints. */ + +static void +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; 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->ops = ops; + + mention (b); + update_global_location_list (1); + + return b; +} + +static void +create_fork_vfork_event_catchpoint (int tempflag, char *cond_string, + struct breakpoint_ops *ops) +{ + 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; - update_global_location_list (1); - - - mention (b); -} - -static void -create_fork_event_catchpoint (int tempflag, char *cond_string) -{ - create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_fork); -} - -static void -create_vfork_event_catchpoint (int tempflag, char *cond_string) -{ - create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_vfork); } static void @@ -5023,12 +5145,6 @@ mention (struct breakpoint *b) (b->type == bp_catch_load) ? "load" : "unload", (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)"), @@ -6450,11 +6566,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")); @@ -6651,6 +6769,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 @@ -7617,8 +7738,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; @@ -7888,10 +8008,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: @@ -8022,10 +8141,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: diff -r c9da7894e8d5 gdb/breakpoint.h --- a/gdb/breakpoint.h Sun Oct 05 16:06:42 2008 -0700 +++ b/gdb/breakpoint.h Mon Oct 06 13:05:03 2008 -0400 @@ -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 *); diff -r c9da7894e8d5 gdb/testsuite/gdb.base/foll-fork.exp --- a/gdb/testsuite/gdb.base/foll-fork.exp Sun Oct 05 16:06:42 2008 -0700 +++ b/gdb/testsuite/gdb.base/foll-fork.exp Mon Oct 06 13:05:03 2008 -0400 @@ -158,14 +158,11 @@ proc catch_fork_child_follow {} { # Verify that the catchpoint is mentioned in an "info breakpoints", # and further that the catchpoint mentions no process id. # - send_gdb "info breakpoints\n" - gdb_expect { - -re ".*catch fork.*keep y.*$gdb_prompt $"\ - {pass "info shows catchpoint without pid"} - -re ".*catch fork.*process .*$gdb_prompt $"\ - {fail "info shows catchpoint without pid"} - -re "$gdb_prompt $" {fail "info shows catchpoint without pid"} - timeout {fail "(timeout) info shows catchpoint without pid"} + set test_name "info shows catchpoint without pid" + gdb_test_multiple "info breakpoints" "$test_name" { + -re ".*catchpoint.*keep y.*fork\[\r\n\]+$gdb_prompt $" { + pass "$test_name" + } } send_gdb "continue\n" @@ -179,12 +176,11 @@ proc catch_fork_child_follow {} { # Verify that the catchpoint is mentioned in an "info breakpoints", # and further that the catchpoint managed to capture a process id. # - send_gdb "info breakpoints\n" - gdb_expect { - -re ".*catch fork .*process \[0-9\]+.*$gdb_prompt $"\ - {pass "info shows catchpoint pid"} - -re "$gdb_prompt $" {fail "info shows catchpoint pid"} - timeout {fail "(timeout) info shows catchpoint pid"} + set test_name "info shows catchpoint without pid" + gdb_test_multiple "info breakpoints" "$test_name" { + -re ".*catchpoint.*keep y.*fork, process.*$gdb_prompt $" { + pass "$test_name" + } } send_gdb "set follow child\n" --oyUTqETQ0mS9luUI--