From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2058 invoked by alias); 17 Aug 2010 19:41:26 -0000 Received: (qmail 2041 invoked by uid 22791); 17 Aug 2010 19:41:23 -0000 X-SWARE-Spam-Status: No, hits=-0.7 required=5.0 tests=AWL,BAYES_20,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from e24smtp03.br.ibm.com (HELO e24smtp03.br.ibm.com) (32.104.18.24) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 17 Aug 2010 19:41:16 +0000 Received: from d24relay01.br.ibm.com (d24relay01.br.ibm.com [9.8.31.16]) by e24smtp03.br.ibm.com (8.14.4/8.13.1) with ESMTP id o7HJcJY7014650 for ; Tue, 17 Aug 2010 16:38:19 -0300 Received: from d24av04.br.ibm.com (d24av04.br.ibm.com [9.8.31.97]) by d24relay01.br.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id o7HJet1v2404588 for ; Tue, 17 Aug 2010 16:40:55 -0300 Received: from d24av04.br.ibm.com (loopback [127.0.0.1]) by d24av04.br.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id o7HJfCGt027533 for ; Tue, 17 Aug 2010 16:41:12 -0300 Received: from [9.78.145.3] ([9.78.145.3]) by d24av04.br.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id o7HJfBNj027529 for ; Tue, 17 Aug 2010 16:41:11 -0300 Subject: [patch 1/2] Convert hardware watchpoints to use breakpoint_ops From: Thiago Jung Bauermann To: gdb-patches ml Content-Type: text/plain; charset="UTF-8" Date: Tue, 17 Aug 2010 19:41:00 -0000 Message-ID: <1282074071.2606.702.camel@hactar> Mime-Version: 1.0 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes 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: 2010-08/txt/msg00274.txt.bz2 Hi all, So I'm continuing my saga of submitting the patches implementing advanced hardware debug features of the PowerPC BookE processors... This one is in preparation for the patch for masked hardware watchpoints and ranged hardware watchpoints. The next e-mail will explain better what they are. The point of this patch is that previous incarnations of the masked and ranged hardware watchpoint implementation added many special cases in breakpoint.c and by using the breakpoint_ops infrastructure most of them can be eliminated. This follows a suggestion Joel made once when reviewing the patch on ranged and masked breakpoints (which I'll submit again later): > In terms of implementation, I'm almost thinking that this type of > breakpoint should be implemented using the breakpoint_ops structure. > It would cause a bit of code redundancy, but your patch is typically > doing: > > if (is_range_breakpoint (...)) > { > do something > } > else > { > do the regular thing; > } > > I'll let you explore this and let me know what you think. I'm 50/50 > on this suggestion, as it has pros and cons. The advantage is that > you no longer have to check for the type of hw_breakpoint that you > have. > I can immediately assume that this is the type that you have. The > downside is a bit of code duplication in how we display the > information. > We might be able to work around this by factorizing the code out of > print_it_typical, print_one_breakpoint_location, etc... This patch actually fixes some inconsistencies in the catchpoints support: target.c sets the default implementation of to_remove_{fork,vfork,exec}_catchpoint to be tcomplain, which throws an exception, but remove_breakpoint_1 is not prepared to deal with it. The only target which implements catchpoints is linux-nat.c and it doesn't actually implement the to_remove_* methods, so in theory an exception would be thrown when GDB tried to remove the catchpoints. The only reason it works is that inf-child.c implements the remove methods to return 0 indicating that the target doesn't support the feature and linux-nat.c inherits those... Also, remove_breakpoint_1 expects breakpoint_ops.remove to return 0 on success and 1 on failure, but as I mentioned before inf-child.c uses a different convention. This patch makes breakpoint_ops.insert and breakpoint_ops.remove use the same convention used by target_insert_watchpoint and target_remove_watchpoint, and they don't throw exceptions anymore. I could have implement the print_* methods for watchpoints which would IMHO make watchpoint handling more object-oriented (= organized? :-) ), but it would actually make the code slightly bigger (one switch statement to distinguish between bp_hardware_watchpoint, bp_read_watchpoint and bp_access_watchpoint per method) so I left this out. I can implement them if you think it's a good idea. Tested on ppc-linux, ppc64-linux and i686-linux with no regressions. Ok to commit? -- []'s Thiago Jung Bauermann IBM Linux Technology Center 2010-08-17 Thiago Jung Bauermann Convert hardware watchpoints to use breakpoint_ops. gdb/ * breakpoint.c (insert_catchpoint): Delete function. (update_watchpoint): Save and restore OPS to/from OLD_OPS when changing the type of the watchpoint. (insert_bp_location): Call the watchpoint or catchpoint's breakpoint_ops.insert method. (remove_breakpoint_1): Call the watchpoint or catchpoint's breakpoint_ops.remove method. (set_raw_breakpoint_without_location): Initialize the OLD_OPS field. (insert_watchpoint, remove_watchpoint): New functions. (watchpoint_breakpoint_ops): New structure. (watch_command_1): Initialize the OPS field. * breakpoint.h (breakpoint_ops) : Return int instead of void. Accept pointer to struct bp_location instead of pointer to struct breakpoint. Adapt all implementations. (breakpoint_ops) : Accept pointer to struct bp_location instead of pointer to struct breakpoint. Adapt all implementations. (breakpoint) : New field. * inf-child.c (inf_child_insert_fork_catchpoint) (inf_child_remove_fork_catchpoint, inf_child_insert_vfork_catchpoint) (inf_child_remove_vfork_catchpoint, inf_child_insert_exec_catchpoint) (inf_child_remove_exec_catchpoint, inf_child_set_syscall_catchpoint): Delete functions. (inf_child_target): Remove initialization of to_insert_fork_catchpoint, to_remove_fork_catchpoint, to_insert_vfork_catchpoint, to_remove_vfork_catchpoint, to_insert_exec_catchpoint, to_remove_exec_catchpoint and to_set_syscall_catchpoint. * target.c (update_current_target): Change default implementation of to_insert_fork_catchpoint, to_remove_fork_catchpoint, to_insert_vfork_catchpoint, to_remove_vfork_catchpoint, to_insert_exec_catchpoint, to_remove_exec_catchpoint and to_set_syscall_catchpoint to return_one. (debug_to_insert_fork_catchpoint, debug_to_insert_vfork_catchpoint) (debug_to_insert_exec_catchpoint): Report return value. * target.h (to_insert_fork_catchpoint, to_insert_vfork_catchpoint) (to_insert_fork_catchpoint): Change declaration to return int instead of void. gdb/testsuite/ * gdb.base/foll-exec.exp: Adapt to new error string when the catchpoint type is not supported. * gdb.base/foll-fork.exp: Likewise. * gdb.base/foll-vfork.exp: Likewise. Index: gdb.git/gdb/breakpoint.c =================================================================== --- gdb.git.orig/gdb/breakpoint.c 2010-08-16 20:17:16.000000000 -0300 +++ gdb.git/gdb/breakpoint.c 2010-08-16 20:17:23.000000000 -0300 @@ -1194,18 +1194,6 @@ breakpoint_restore_shadows (gdb_byte *bu } -/* A wrapper function for inserting catchpoints. */ -static void -insert_catchpoint (struct ui_out *uo, void *args) -{ - struct breakpoint *b = (struct breakpoint *) args; - - gdb_assert (b->type == bp_catchpoint); - gdb_assert (b->ops != NULL && b->ops->insert != NULL); - - b->ops->insert (b); -} - /* Return true if BPT is of any hardware watchpoint kind. */ static int @@ -1420,15 +1408,37 @@ update_watchpoint (struct breakpoint *b, mem_cnt = can_use_hardware_watchpoint (val_chain); if (!mem_cnt) - b->type = bp_watchpoint; + { + b->type = bp_watchpoint; + + /* When downgrading to a software watchpoint, we have to + remember the value of the OPS field so that we can restore + it when upgrading to a hardware watchpoint again. */ + if (b->ops) + { + b->old_ops = b->ops; + b->ops = NULL; + } + } else { int target_resources_ok = target_can_use_hardware_watchpoint (bp_hardware_watchpoint, i + mem_cnt, other_type_used); if (target_resources_ok <= 0) - b->type = bp_watchpoint; + { + b->type = bp_watchpoint; + if (b->ops) + { + b->old_ops = b->ops; + b->ops = NULL; + } + } else - b->type = bp_hardware_watchpoint; + { + b->type = bp_hardware_watchpoint; + if (b->old_ops) + b->ops = b->old_ops; + } } } @@ -1742,10 +1752,7 @@ Note: automatically using hardware break watchpoints. It's not clear that it's necessary... */ && bpt->owner->disposition != disp_del_at_next_stop) { - val = target_insert_watchpoint (bpt->address, - bpt->length, - bpt->watchpoint_type, - bpt->owner->cond_exp); + val = bpt->owner->ops->insert (bpt); /* If trying to set a read-watchpoint, and it turns out it's not supported, try emulating one with an access watchpoint. */ @@ -1771,12 +1778,12 @@ Note: automatically using hardware break if (val == 1) { - val = target_insert_watchpoint (bpt->address, - bpt->length, - hw_access, - bpt->owner->cond_exp); - if (val == 0) - bpt->watchpoint_type = hw_access; + bpt->watchpoint_type = hw_access; + val = bpt->owner->ops->insert (bpt); + + if (val) + /* Back to the original value. */ + bpt->watchpoint_type = hw_read; } } @@ -1785,14 +1792,22 @@ Note: automatically using hardware break else if (bpt->owner->type == bp_catchpoint) { - struct gdb_exception e = catch_exception (uiout, insert_catchpoint, - bpt->owner, RETURN_MASK_ERROR); - exception_fprintf (gdb_stderr, e, "warning: inserting catchpoint %d: ", - bpt->owner->number); - if (e.reason < 0) - bpt->owner->enable_state = bp_disabled; - else - bpt->inserted = 1; + gdb_assert (bpt->owner->ops != NULL && bpt->owner->ops->insert != NULL); + + val = bpt->owner->ops->insert (bpt); + if (val) + { + bpt->owner->enable_state = bp_disabled; + + if (val == 1) + warning (_("\ +Inserting catchpoint %d: Your system does not support this type of catchpoint."), + bpt->owner->number); + else + warning (_("Error inserting catchpoint %d."), bpt->owner->number); + } + + bpt->inserted = (val == 0); /* We've already printed an error message if there was a problem inserting this catchpoint, and we've disabled the catchpoint, @@ -2443,8 +2458,7 @@ remove_breakpoint_1 (struct bp_location else if (b->loc_type == bp_loc_hardware_watchpoint) { b->inserted = (is == mark_inserted); - val = target_remove_watchpoint (b->address, b->length, - b->watchpoint_type, b->owner->cond_exp); + b->owner->ops->remove (b); /* Failure to remove any of the hardware watchpoints comes here. */ if ((is == mark_uninserted) && (b->inserted)) @@ -2457,9 +2471,10 @@ remove_breakpoint_1 (struct bp_location { gdb_assert (b->owner->ops != NULL && b->owner->ops->remove != NULL); - val = b->owner->ops->remove (b->owner); + val = b->owner->ops->remove (b); if (val) return val; + b->inserted = (is == mark_inserted); } @@ -5426,6 +5441,7 @@ set_raw_breakpoint_without_location (str b->exec_pathname = NULL; b->syscalls_to_be_caught = NULL; b->ops = NULL; + b->old_ops = NULL; b->condition_not_parsed = 0; /* Add this breakpoint to the end of the chain @@ -5809,16 +5825,16 @@ disable_breakpoints_in_unloaded_shlib (s /* Implement the "insert" breakpoint_ops method for fork catchpoints. */ -static void -insert_catch_fork (struct breakpoint *b) +static int +insert_catch_fork (struct bp_location *b) { - target_insert_fork_catchpoint (PIDGET (inferior_ptid)); + return target_insert_fork_catchpoint (PIDGET (inferior_ptid)); } /* Implement the "remove" breakpoint_ops method for fork catchpoints. */ static int -remove_catch_fork (struct breakpoint *b) +remove_catch_fork (struct bp_location *b) { return target_remove_fork_catchpoint (PIDGET (inferior_ptid)); } @@ -5901,16 +5917,16 @@ static struct breakpoint_ops catch_fork_ /* Implement the "insert" breakpoint_ops method for vfork catchpoints. */ -static void -insert_catch_vfork (struct breakpoint *b) +static int +insert_catch_vfork (struct bp_location *b) { - target_insert_vfork_catchpoint (PIDGET (inferior_ptid)); + return target_insert_vfork_catchpoint (PIDGET (inferior_ptid)); } /* Implement the "remove" breakpoint_ops method for vfork catchpoints. */ static int -remove_catch_vfork (struct breakpoint *b) +remove_catch_vfork (struct bp_location *b) { return target_remove_vfork_catchpoint (PIDGET (inferior_ptid)); } @@ -5993,20 +6009,20 @@ static struct breakpoint_ops catch_vfork /* Implement the "insert" breakpoint_ops method for syscall catchpoints. */ -static void -insert_catch_syscall (struct breakpoint *b) +static int +insert_catch_syscall (struct bp_location *b) { struct inferior *inf = current_inferior (); ++inf->total_syscalls_count; - if (!b->syscalls_to_be_caught) + if (!b->owner->syscalls_to_be_caught) ++inf->any_syscall_count; else { int i, iter; for (i = 0; - VEC_iterate (int, b->syscalls_to_be_caught, i, iter); + VEC_iterate (int, b->owner->syscalls_to_be_caught, i, iter); i++) { int elem; @@ -6027,30 +6043,30 @@ insert_catch_syscall (struct breakpoint } } - target_set_syscall_catchpoint (PIDGET (inferior_ptid), - inf->total_syscalls_count != 0, - inf->any_syscall_count, - VEC_length (int, inf->syscalls_counts), - VEC_address (int, inf->syscalls_counts)); + return target_set_syscall_catchpoint (PIDGET (inferior_ptid), + inf->total_syscalls_count != 0, + inf->any_syscall_count, + VEC_length (int, inf->syscalls_counts), + VEC_address (int, inf->syscalls_counts)); } /* Implement the "remove" breakpoint_ops method for syscall catchpoints. */ static int -remove_catch_syscall (struct breakpoint *b) +remove_catch_syscall (struct bp_location *b) { struct inferior *inf = current_inferior (); --inf->total_syscalls_count; - if (!b->syscalls_to_be_caught) + if (!b->owner->syscalls_to_be_caught) --inf->any_syscall_count; else { int i, iter; for (i = 0; - VEC_iterate (int, b->syscalls_to_be_caught, i, iter); + VEC_iterate (int, b->owner->syscalls_to_be_caught, i, iter); i++) { int elem; @@ -6349,14 +6365,14 @@ create_fork_vfork_event_catchpoint (stru /* Exec catchpoints. */ -static void -insert_catch_exec (struct breakpoint *b) +static int +insert_catch_exec (struct bp_location *b) { - target_insert_exec_catchpoint (PIDGET (inferior_ptid)); + return target_insert_exec_catchpoint (PIDGET (inferior_ptid)); } static int -remove_catch_exec (struct breakpoint *b) +remove_catch_exec (struct bp_location *b) { return target_remove_exec_catchpoint (PIDGET (inferior_ptid)); } @@ -7984,6 +8000,37 @@ watchpoint_exp_is_const (const struct ex return 1; } +/* Implement the "insert" breakpoint_ops method for hardware watchpoints. */ + +static int +insert_watchpoint (struct bp_location *bpt) +{ + return target_insert_watchpoint (bpt->address, bpt->length, + bpt->watchpoint_type, bpt->owner->cond_exp); +} + +/* Implement the "remove" breakpoint_ops method for hardware watchpoints. */ + +static int +remove_watchpoint (struct bp_location *bpt) +{ + return target_remove_watchpoint (bpt->address, bpt->length, + bpt->watchpoint_type, bpt->owner->cond_exp); +} + +/* The breakpoint_ops structure to be used in hardware watchpoints. */ + +static struct breakpoint_ops watchpoint_breakpoint_ops = +{ + insert_watchpoint, + remove_watchpoint, + NULL, /* breakpoint_hit */ + NULL, /* print_it */ + NULL, /* print_one */ + NULL, /* print_mention */ + NULL /* print_recreate */ +}; + /* accessflag: hw_write: watch write, hw_read: watch read, hw_access: watch access (read or write) */ @@ -8226,6 +8273,8 @@ watch_command_1 (char *arg, int accessfl b->exp_string = savestring (exp_start, exp_end - exp_start); b->val = val; b->val_valid = 1; + b->ops = &watchpoint_breakpoint_ops; + if (cond_start) b->cond_string = savestring (cond_start, cond_end - cond_start); else Index: gdb.git/gdb/breakpoint.h =================================================================== --- gdb.git.orig/gdb/breakpoint.h 2010-08-16 20:17:16.000000000 -0300 +++ gdb.git/gdb/breakpoint.h 2010-08-16 20:17:23.000000000 -0300 @@ -339,16 +339,18 @@ struct bp_location will be called instead of the performing the default action for this bptype. */ -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 *); + /* Insert the breakpoint or watchpoint or activate the catchpoint. + Return 0 for success, 1 if the breakpoint, watchpoint or catchpoint + type is not supported, -1 for failure. */ + int (*insert) (struct bp_location *); /* Remove the breakpoint/catchpoint that was previously inserted - with the "insert" method above. Return non-zero if the operation - succeeded. */ - int (*remove) (struct breakpoint *); + with the "insert" method above. Return 0 for success, 1 if the + breakpoint, watchpoint or catchpoint type is not supported, + -1 for failure. */ + int (*remove) (struct bp_location *); /* Return non-zero if the debugger should tell the user that this breakpoint was hit. */ @@ -525,6 +527,11 @@ struct breakpoint /* Methods associated with this breakpoint. */ struct breakpoint_ops *ops; + /* When a watchpoint changes from hardware to software watchpoint, its + OPS field will be set to NULL. We need to remember its original value + so that we can restore it if the watchpoint is upgraded again later. */ + struct breakpoint_ops *old_ops; + /* Is breakpoint's condition not yet parsed because we found no location initially so had no context to parse the condition in. */ Index: gdb.git/gdb/inf-child.c =================================================================== --- gdb.git.orig/gdb/inf-child.c 2010-08-16 20:17:16.000000000 -0300 +++ gdb.git/gdb/inf-child.c 2010-08-16 20:17:23.000000000 -0300 @@ -94,36 +94,6 @@ inf_child_acknowledge_created_inferior ( created inferior" operation by a debugger. */ } -static void -inf_child_insert_fork_catchpoint (int pid) -{ - /* This version of Unix doesn't support notification of fork - events. */ -} - -static int -inf_child_remove_fork_catchpoint (int pid) -{ - /* This version of Unix doesn't support notification of fork - events. */ - return 0; -} - -static void -inf_child_insert_vfork_catchpoint (int pid) -{ - /* This version of Unix doesn't support notification of vfork - events. */ -} - -static int -inf_child_remove_vfork_catchpoint (int pid) -{ - /* This version of Unix doesn't support notification of vfork - events. */ - return 0; -} - static int inf_child_follow_fork (struct target_ops *ops, int follow_child) { @@ -132,30 +102,6 @@ inf_child_follow_fork (struct target_ops return 0; } -static void -inf_child_insert_exec_catchpoint (int pid) -{ - /* This version of Unix doesn't support notification of exec - events. */ -} - -static int -inf_child_remove_exec_catchpoint (int pid) -{ - /* This version of Unix doesn't support notification of exec - events. */ - return 0; -} - -static int -inf_child_set_syscall_catchpoint (int pid, int needed, int any_count, - int table_size, int *table) -{ - /* This version of Unix doesn't support notification of syscall - events. */ - return 0; -} - static int inf_child_can_run (void) { @@ -193,14 +139,7 @@ inf_child_target (void) t->to_terminal_info = child_terminal_info; t->to_post_startup_inferior = inf_child_post_startup_inferior; t->to_acknowledge_created_inferior = inf_child_acknowledge_created_inferior; - t->to_insert_fork_catchpoint = inf_child_insert_fork_catchpoint; - t->to_remove_fork_catchpoint = inf_child_remove_fork_catchpoint; - t->to_insert_vfork_catchpoint = inf_child_insert_vfork_catchpoint; - t->to_remove_vfork_catchpoint = inf_child_remove_vfork_catchpoint; t->to_follow_fork = inf_child_follow_fork; - t->to_insert_exec_catchpoint = inf_child_insert_exec_catchpoint; - t->to_remove_exec_catchpoint = inf_child_remove_exec_catchpoint; - t->to_set_syscall_catchpoint = inf_child_set_syscall_catchpoint; t->to_can_run = inf_child_can_run; t->to_pid_to_exec_file = inf_child_pid_to_exec_file; t->to_stratum = process_stratum; Index: gdb.git/gdb/linux-nat.c =================================================================== --- gdb.git.orig/gdb/linux-nat.c 2010-08-16 20:17:16.000000000 -0300 +++ gdb.git/gdb/linux-nat.c 2010-08-16 20:17:23.000000000 -0300 @@ -961,36 +961,34 @@ Attaching after process %d fork to child } -static void +static int linux_child_insert_fork_catchpoint (int pid) { - if (! linux_supports_tracefork (pid)) - error (_("Your system does not support fork catchpoints.")); + return !linux_supports_tracefork (pid); } -static void +static int linux_child_insert_vfork_catchpoint (int pid) { - if (!linux_supports_tracefork (pid)) - error (_("Your system does not support vfork catchpoints.")); + return !linux_supports_tracefork (pid); } -static void +static int linux_child_insert_exec_catchpoint (int pid) { - if (!linux_supports_tracefork (pid)) - error (_("Your system does not support exec catchpoints.")); + return !linux_supports_tracefork (pid); } static int linux_child_set_syscall_catchpoint (int pid, int needed, int any_count, int table_size, int *table) { - if (! linux_supports_tracesysgood (pid)) - error (_("Your system does not support syscall catchpoints.")); + if (!linux_supports_tracesysgood (pid)) + return 1; + /* On GNU/Linux, we ignore the arguments. It means that we only enable the syscall catchpoints, but do not disable them. - + Also, we do not use the `table' information because we do not filter system calls here. We let GDB do the logic for us. */ return 0; Index: gdb.git/gdb/target.c =================================================================== --- gdb.git.orig/gdb/target.c 2010-08-16 20:17:16.000000000 -0300 +++ gdb.git/gdb/target.c 2010-08-16 20:17:23.000000000 -0300 @@ -782,26 +782,26 @@ update_current_target (void) (void (*) (int)) target_ignore); de_fault (to_insert_fork_catchpoint, - (void (*) (int)) - tcomplain); + (int (*) (int)) + return_one); de_fault (to_remove_fork_catchpoint, (int (*) (int)) - tcomplain); + return_one); de_fault (to_insert_vfork_catchpoint, - (void (*) (int)) - tcomplain); + (int (*) (int)) + return_one); de_fault (to_remove_vfork_catchpoint, (int (*) (int)) - tcomplain); + return_one); de_fault (to_insert_exec_catchpoint, - (void (*) (int)) - tcomplain); + (int (*) (int)) + return_one); de_fault (to_remove_exec_catchpoint, (int (*) (int)) - tcomplain); + return_one); de_fault (to_set_syscall_catchpoint, (int (*) (int, int, int, int, int *)) - tcomplain); + return_one); de_fault (to_has_exited, (int (*) (int, int, int *)) return_zero); @@ -3657,13 +3657,17 @@ debug_to_acknowledge_created_inferior (i pid); } -static void +static int debug_to_insert_fork_catchpoint (int pid) { - debug_target.to_insert_fork_catchpoint (pid); + int retval; - fprintf_unfiltered (gdb_stdlog, "target_insert_fork_catchpoint (%d)\n", - pid); + retval = debug_target.to_insert_fork_catchpoint (pid); + + fprintf_unfiltered (gdb_stdlog, "target_insert_fork_catchpoint (%d) = %d\n", + pid, retval); + + return retval; } static int @@ -3679,13 +3683,17 @@ debug_to_remove_fork_catchpoint (int pid return retval; } -static void +static int debug_to_insert_vfork_catchpoint (int pid) { - debug_target.to_insert_vfork_catchpoint (pid); + int retval; - fprintf_unfiltered (gdb_stdlog, "target_insert_vfork_catchpoint (%d)\n", - pid); + retval = debug_target.to_insert_vfork_catchpoint (pid); + + fprintf_unfiltered (gdb_stdlog, "target_insert_vfork_catchpoint (%d) = %d\n", + pid, retval); + + return retval; } static int @@ -3701,13 +3709,17 @@ debug_to_remove_vfork_catchpoint (int pi return retval; } -static void +static int debug_to_insert_exec_catchpoint (int pid) { - debug_target.to_insert_exec_catchpoint (pid); + int retval; - fprintf_unfiltered (gdb_stdlog, "target_insert_exec_catchpoint (%d)\n", - pid); + retval = debug_target.to_insert_exec_catchpoint (pid); + + fprintf_unfiltered (gdb_stdlog, "target_insert_exec_catchpoint (%d) = %d\n", + pid, retval); + + return retval; } static int Index: gdb.git/gdb/target.h =================================================================== --- gdb.git.orig/gdb/target.h 2010-08-16 20:17:16.000000000 -0300 +++ gdb.git/gdb/target.h 2010-08-16 20:17:23.000000000 -0300 @@ -468,12 +468,12 @@ struct target_ops char *, char *, char **, int); void (*to_post_startup_inferior) (ptid_t); void (*to_acknowledge_created_inferior) (int); - void (*to_insert_fork_catchpoint) (int); + int (*to_insert_fork_catchpoint) (int); int (*to_remove_fork_catchpoint) (int); - void (*to_insert_vfork_catchpoint) (int); + int (*to_insert_vfork_catchpoint) (int); int (*to_remove_vfork_catchpoint) (int); int (*to_follow_fork) (struct target_ops *, int); - void (*to_insert_exec_catchpoint) (int); + int (*to_insert_exec_catchpoint) (int); int (*to_remove_exec_catchpoint) (int); int (*to_set_syscall_catchpoint) (int, int, int, int, int *); int (*to_has_exited) (int, int, int *); @@ -1087,7 +1087,10 @@ int target_follow_fork (int follow_child TABLE is an array of ints, indexed by syscall number. An element in this array is nonzero if that syscall should be caught. This argument - only matters if ANY_COUNT is zero. */ + only matters if ANY_COUNT is zero. + + Return 0 for success, 1 if syscall catchpoints are not supported or -1 + for failure. */ #define target_set_syscall_catchpoint(pid, needed, any_count, table_size, table) \ (*current_target.to_set_syscall_catchpoint) (pid, needed, any_count, \ Index: gdb.git/gdb/testsuite/gdb.base/foll-exec.exp =================================================================== --- gdb.git.orig/gdb/testsuite/gdb.base/foll-exec.exp 2010-08-16 20:17:16.000000000 -0300 +++ gdb.git/gdb/testsuite/gdb.base/foll-exec.exp 2010-08-16 20:17:23.000000000 -0300 @@ -89,7 +89,7 @@ proc do_exec_tests {} { gdb_test "catch exec" "Catchpoint \[0-9\]* \\(exec\\)" "insert first exec catchpoint" set has_exec_catchpoints 0 gdb_test_multiple "continue" "continue to first exec catchpoint" { - -re ".*Your system does not support exec catchpoints.*$gdb_prompt $" { + -re ".*Your system does not support this type of catchpoint.*$gdb_prompt $" { unsupported "continue to first exec catchpoint" } -re ".*Catchpoint.*$gdb_prompt $" { Index: gdb.git/gdb/testsuite/gdb.base/foll-fork.exp =================================================================== --- gdb.git.orig/gdb/testsuite/gdb.base/foll-fork.exp 2010-08-16 20:17:16.000000000 -0300 +++ gdb.git/gdb/testsuite/gdb.base/foll-fork.exp 2010-08-16 20:17:23.000000000 -0300 @@ -45,7 +45,7 @@ proc check_fork_catchpoints {} { gdb_test "catch fork" "Catchpoint \[0-9\]* \\(fork\\)" "insert first fork catchpoint" set has_fork_catchpoints 0 gdb_test_multiple "continue" "continue to first fork catchpoint" { - -re ".*Your system does not support fork catchpoints.*$gdb_prompt $" { + -re ".*Your system does not support this type of catchpoint.*$gdb_prompt $" { unsupported "continue to first fork catchpoint" } -re ".*Catchpoint.*$gdb_prompt $" { Index: gdb.git/gdb/testsuite/gdb.base/foll-vfork.exp =================================================================== --- gdb.git.orig/gdb/testsuite/gdb.base/foll-vfork.exp 2010-08-16 20:17:16.000000000 -0300 +++ gdb.git/gdb/testsuite/gdb.base/foll-vfork.exp 2010-08-16 20:17:23.000000000 -0300 @@ -74,7 +74,7 @@ proc check_vfork_catchpoints {} { gdb_test "catch vfork" "Catchpoint \[0-9\]* \\(vfork\\)" "insert first vfork catchpoint" set has_vfork_catchpoints 0 gdb_test_multiple "continue" "continue to first vfork catchpoint" { - -re ".*Your system does not support vfork catchpoints.*$gdb_prompt $" { + -re ".*Your system does not support this type of catchpoint.*$gdb_prompt $" { unsupported "continue to first vfork catchpoint" } -re ".*Catchpoint.*$gdb_prompt $" {