From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9478 invoked by alias); 7 May 2003 21:45:08 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 9463 invoked from network); 7 May 2003 21:45:07 -0000 Received: from unknown (HELO cygnus.equallogic.com) (65.170.102.10) by sources.redhat.com with SMTP; 7 May 2003 21:45:07 -0000 Received: from cygnus.equallogic.com (localhost.localdomain [127.0.0.1]) by cygnus.equallogic.com (8.11.6/8.11.6) with ESMTP id h47Lj7t09024 for ; Wed, 7 May 2003 17:45:07 -0400 Received: from deneb.dev.equallogic.com (deneb.dev.equallogic.com [172.16.1.99]) by cygnus.equallogic.com (8.11.6/8.11.6) with ESMTP id h47Lj7r09018 for ; Wed, 7 May 2003 17:45:07 -0400 Received: from pkoning.dev.equallogic.com.equallogic.com (localhost.localdomain [127.0.0.1]) by deneb.dev.equallogic.com (8.11.6/8.11.6) with ESMTP id h47Lj6B18101 for ; Wed, 7 May 2003 17:45:07 -0400 Message-ID: <16057.32335.33047.496741@pkoning.dev.equallogic.com> Date: Wed, 07 May 2003 21:45:00 -0000 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit From: Paul Koning To: gdb@sources.redhat.com Subject: Re: watchpoint troubles References: <16057.18767.270168.635955@pkoning.dev.equallogic.com> <20030507183329.88D0B7885A@deneb.localdomain> <16057.22019.173960.269354@pkoning.dev.equallogic.com> X-SW-Source: 2003-05/txt/msg00097.txt.bz2 >>>>> "Paul" == Paul Koning writes: >>>>> "Mark" == Mark Salter writes: >>>>> Paul Koning writes: >>> I'm having all sorts of watchpoint troubles with gdb 5.3 and a >>> remote target. These are things I'm running into as I'm working >>> to improve the implementation of watchpoints in my remote stub. Mark> ... >>> Without that flag, the first thing that gdb does after the >>> watchpoint entry is to read the address being watched. Needless >>> to say, that causes a watchpoint recursion within the target >>> stub. In the case where HAVE_NONSTEPPABLE_WATCHPOINT is defined, >>> things work because the watchpoint is removed before the memory >>> read request is made. >>> Since gdb normally removes and reinserts watch/break points on >>> every entry, I figured it's gdb's job to do things in the right >>> order. Bad assumption? I can certainly hack up the stub to >>> remove the watchpoints before acting on any memory access >>> requests from gdb, but is that kind of hackery supposed to be >>> done? Mark> This has come up before: Mark> http://sources.redhat.com/ml/gdb-patches/2001-03/msg00506.html Mark> I think the answer is that the stub should disable watchpoints Mark> anytime the target stops and reenable them when stepping or Mark> continuing. Paul> Thanks. Paul> I just read that thread and the final message seems to say "gdb Paul> can be fixed to remove the watchpoints before doing the memory Paul> read in the case where HAVE_NONSTEPPABLE_WATCHPOINT is Paul> undefined. Yes, I thought so. Paul> I may do that just to try it. As I mentioned, what I *really* Paul> want is for the case where HAVE_NONSTEPPABLE_WATCHPOINT *is* Paul> defined to work correctly. Right now it doesn't. Ok, so after some messing around I did get things to work. The case I care about is where HAVE_NONSTEPPABLE_WATCHPOINT is defined, so I created what looks like the minimal patch for that. See below. For the case where HAVE_NONSTEPPABLE_WATCHPOINT is *not* defined, this doesn't quite work because then the watchpoint is still enabled, so if the stub doesn't protect itself then you're in trouble. That can be addressed (given the other changes in the patch) by also doing a remove_breakpoints() for that case. I didn't bother because that case doesn't matter to me. The patch is somewhat ugly because it ties into remote.c. There may be a cleaner way but I'm not sure which route it should take. paul Index: breakpoint.c =================================================================== RCS file: /home/cvs/console_gdb/gdb/breakpoint.c,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 breakpoint.c --- breakpoint.c 3 Oct 2002 19:49:14 -0000 1.1.1.2 +++ breakpoint.c 7 May 2003 21:39:18 -0000 @@ -704,6 +704,22 @@ } +/* Helper routine: free the value chain for a breakpoint (watchpoint) */ +static void free_valchain (struct breakpoint *b) +{ + struct value *v; + struct value *n; + + /* Free the saved value chain. We will construct a new one + the next time the watchpoint is inserted. */ + for (v = b->val_chain; v; v = n) + { + n = v->next; + value_free (v); + } + b->val_chain = NULL; +} + /* insert_breakpoints is used when starting or continuing the program. remove_breakpoints is used when the program stops. Both return zero if successful, @@ -961,6 +977,8 @@ if (within_current_scope) { + free_valchain (b); + /* Evaluate the expression and cut the chain of values produced off from the value chain. @@ -970,7 +988,7 @@ v = evaluate_expression (b->exp); VALUE_CONTENTS(v); value_release_to_mark (mark); - + b->val_chain = v; b->inserted = 1; @@ -1461,15 +1479,6 @@ if ((is == mark_uninserted) && (b->inserted)) warning ("Could not remove hardware watchpoint %d.", b->number); - - /* Free the saved value chain. We will construct a new one - the next time the watchpoint is inserted. */ - for (v = b->val_chain; v; v = n) - { - n = v->next; - value_free (v); - } - b->val_chain = NULL; } else if ((b->type == bp_catch_fork || b->type == bp_catch_vfork || @@ -2633,8 +2642,12 @@ int found = 0; addr = target_stopped_data_address (); - if (addr == 0) + if (addr == 0) { + bs->print_it = print_it_noop; + bs->stop = 0; continue; + } + for (v = b->val_chain; v; v = v->next) { if (VALUE_LVAL (v) == lval_memory @@ -6679,6 +6692,8 @@ if (bpt->inserted) remove_breakpoint (bpt, mark_inserted); + free_valchain (bpt); + if (breakpoint_chain == bpt) breakpoint_chain = bpt->next; Index: infrun.c =================================================================== RCS file: /home/cvs/console_gdb/gdb/infrun.c,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 infrun.c --- infrun.c 3 Oct 2002 19:49:36 -0000 1.1.1.2 +++ infrun.c 7 May 2003 21:39:18 -0000 @@ -1389,11 +1389,12 @@ by an event from the inferior, figure out what it means and take appropriate action. */ +int stepped_after_stopped_by_watchpoint; + void handle_inferior_event (struct execution_control_state *ecs) { CORE_ADDR tmp; - int stepped_after_stopped_by_watchpoint; int sw_single_step_trap_p = 0; /* Cache the last pid/waitstatus. */ Index: remote.c =================================================================== RCS file: /home/cvs/console_gdb/gdb/remote.c,v retrieving revision 1.5 diff -u -r1.5 remote.c --- remote.c 7 Oct 2002 20:45:22 -0000 1.5 +++ remote.c 7 May 2003 21:39:19 -0000 @@ -4889,10 +4889,13 @@ return remote_stopped_by_watchpoint_p; } +extern int stepped_after_stopped_by_watchpoint; + CORE_ADDR remote_stopped_data_address (void) { - if (remote_stopped_by_watchpoint ()) + if (remote_stopped_by_watchpoint () || + stepped_after_stopped_by_watchpoint) return remote_watch_data_address; return (CORE_ADDR)0; }