From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21765 invoked by alias); 10 Oct 2005 23:21:33 -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 21684 invoked by uid 22791); 10 Oct 2005 23:21:26 -0000 Received: from hq.tensilica.com (HELO mailapp.tensilica.com) (65.205.227.29) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Mon, 10 Oct 2005 23:21:26 +0000 Received: from localhost ([127.0.0.1] ident=amavis) by mailapp.tensilica.com with esmtp (Exim 4.34) id 1EP6xQ-0001BX-Ia; Mon, 10 Oct 2005 16:21:24 -0700 Received: from mailapp.tensilica.com ([127.0.0.1]) by localhost (mailapp [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 04513-01; Mon, 10 Oct 2005 16:21:24 -0700 (PDT) Received: from nose.hq.tensilica.com ([192.168.10.147]) by mailapp.tensilica.com with esmtp (Exim 4.34) id 1EP6xQ-0001BR-3a; Mon, 10 Oct 2005 16:21:24 -0700 Message-ID: <434AF774.5050808@tensilica.com> Date: Mon, 10 Oct 2005 23:21:00 -0000 From: Ross Morley User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.2) Gecko/20040805 Netscape/7.2 MIME-Version: 1.0 To: gdb@sources.redhat.com CC: Thomas Covenant Subject: Re: When do watchpoints go out of scope? References: <20050925143734.65016.qmail@web34809.mail.mud.yahoo.com> <20050925172535.GA15486@nevyn.them.org> In-Reply-To: <20050925172535.GA15486@nevyn.them.org> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-SW-Source: 2005-10/txt/msg00068.txt.bz2 Daniel Jacobowitz wrote: > On Sun, Sep 25, 2005 at 07:37:34AM -0700, Thomas Covenant wrote: > > >> Consider this program: >> >> 1 int main(void) >> 2 { >> 3 { >> 4 int i = 2; >> 5 printf("i is %d.\n", i); >> 6 i = 3; >> 7 printf("i is %d.\n", i); >> 8 } >> 9 // lots more code >> ... >> 90 return 0; >> 100 } >> >> The variable i goes in scope at line 4, out of scope >> at line 8. >> >> If I set: >> >> watch i >> >> at line 4, I would assume the watchpoint would be >> deleted at line 8, since i is no longer in scope. >> > > > This depends on your compiler and the debug information it generates. > If GDB still has location information, it will continue to watch the > variable. If it doesn't, it will stop. You didn't say what your > platform or compiler was, so it's hard to guess, but many older > versions of GCC and most targets using the stabs format do not have > accurate endings for lifetimes. > > > I'm a few weeks behind on my reading of this list, but... There is a bug. I fixed it recently in our Xtensa port which is still based on GDB 5.2.1. The problem is bpstat_stop_status() fails to delete the watchpoint when it's scope breakpoint is hit (it gets deleted when the program stops for some other reason). In fact it simply forgets to handle the case of a watchpoint scope breakpoint. If you disable the watchpoint and run till it's out of scope, it never gets deleted. A cursory look at the GDB 6.3 source suggests it's still that way. Here's my quick-fix to 5.2.1 (breakpoint.c, added lines marked with +): ------------------------------------------------------------------------ bpstat bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint) { register struct breakpoint *b, *temp; CORE_ADDR bp_addr; /* True if we've hit a breakpoint (as opposed to a watchpoint). */ int real_breakpoint = 0; /* Root of the chain of bpstat's */ struct bpstats root_bs[1]; /* Pointer to the last thing in the chain currently. */ bpstat bs = root_bs; static char message1[] = "Error evaluating expression for watchpoint %d\n"; char message[sizeof (message1) + 30 /* slop */ ]; /* Get the address where the breakpoint would have been. The "not_a_breakpoint" argument is meant to distinguish between a breakpoint trap event and a trace/singlestep trap event. For a trace/singlestep trap event, we would not want to subtract DECR_PC_AFTER_BREAK from the PC. */ bp_addr = *pc - (not_a_breakpoint && !SOFTWARE_SINGLE_STEP_P () ? 0 : DECR_PC_AFTER_BREAK); ALL_BREAKPOINTS_SAFE (b, temp) { if (b->enable_state == bp_disabled || b->enable_state == bp_shlib_disabled || b->enable_state == bp_call_disabled) continue; + /* If we hit a watchpoint scope breakpoint, find the associated watchpoint + and check it's scope (call watchpoint_check) and delete if out of scope. + TODO: Use related_breakpoint field of scope breakpoint to reference wp. */ + if (b->type == bp_watchpoint_scope && b->address == bp_addr) + { + register struct breakpoint *b1, *temp1; + struct bpstats bs1tmp; + bpstat bs1 = &bs1tmp; + struct value *saved_val; + + ALL_BREAKPOINTS_SAFE (b1, temp1) + { + if (b1->related_breakpoint != b) + continue; + + saved_val = b1->val; + bs1->breakpoint_at = b1; + sprintf (message, message1, b1->number); + catch_errors (watchpoint_check, bs1, message, RETURN_MASK_ALL); + /* The deed is done - we don't care about the result. */ + + /* Restore value & disposition in case changed by watchpoint_check(). */ + b1->val = saved_val; + } + } + if (b->type != bp_watchpoint && b->type != bp_hardware_watchpoint && 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_catch_exec && b->type != bp_catch_catch && b->type != bp_catch_throw) /* a non-watchpoint bp */ { if (b->address != bp_addr) /* address doesn't match */ continue; if (overlay_debugging /* unmapped overlay section */ && section_is_overlay (b->section) && !section_is_mapped (b->section)) continue; } ------------------------------------------------------------------------ I can't submit this to the source base because we're not yet up to date. Anyone can feel free to apply this to the top of trunk and improve on it. Ross Morley Tensilica, Inc. > >