Message ID | 20160608130856.GD26734@embecosm.com |
---|---|
State | New, archived |
Headers |
Received: (qmail 61473 invoked by alias); 8 Jun 2016 13:09:12 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: <gdb-patches.sourceware.org> List-Unsubscribe: <mailto:gdb-patches-unsubscribe-##L=##H@sourceware.org> List-Subscribe: <mailto:gdb-patches-subscribe@sourceware.org> List-Archive: <http://sourceware.org/ml/gdb-patches/> List-Post: <mailto:gdb-patches@sourceware.org> List-Help: <mailto:gdb-patches-help@sourceware.org>, <http://sourceware.org/ml/#faqs> Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 61458 invoked by uid 89); 8 Jun 2016 13:09:12 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, URIBL_RED autolearn=ham version=3.3.2 spammy=Hx-languages-length:2454 X-HELO: mail-wm0-f51.google.com Received: from mail-wm0-f51.google.com (HELO mail-wm0-f51.google.com) (74.125.82.51) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 08 Jun 2016 13:09:01 +0000 Received: by mail-wm0-f51.google.com with SMTP id n184so181014199wmn.1 for <gdb-patches@sourceware.org>; Wed, 08 Jun 2016 06:09:01 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=JQfX+X5Sp87SwrkIa7AwL31mWXzt1qowmRMxZPSY1XQ=; b=OtwT8lgOvL1AnGO8V0ymH+P/Wxt0zEkdcB6k1dMwFC0+c02evQw7ssvHbHkxgYZ74g jODdMFnDYy2S/qAUAtJJmZ1eoedMt6sMFWms+XN3Rnk/ZbTFA5Tz4re70i2nZsPKoZRG 5/vMVPhAS47H54Kt4CazkhJ36Gem8HdGrtH3zXR9GDPySXAnxMPcrB4M107DwYUIR7f0 mRgQ+cm+U5MLbeNo0CtCZD5YRgghlipyHAVYwSFVvMSnaBFv9zh0hovU/kiox8CR0kw7 OU81Al25LKgQe0Z49SYdvqExb9O9AdKElxxEk2exwG+BNDQIJWm2isJ/ERoalu1GR8v8 0+0g== X-Gm-Message-State: ALyK8tJpvSSj+kOZdkLHB9csap+USTeE24hviR+Un2aUbH/mVIM0YHPGdDv37jNoAxe9Hg== X-Received: by 10.28.107.67 with SMTP id g64mr7507024wmc.65.1465391339098; Wed, 08 Jun 2016 06:08:59 -0700 (PDT) Received: from localhost (cust64-dsl91-135-5.idnet.net. [91.135.5.64]) by smtp.gmail.com with ESMTPSA id k127sm2030931wmf.21.2016.06.08.06.08.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 08 Jun 2016 06:08:58 -0700 (PDT) Date: Wed, 8 Jun 2016 14:08:56 +0100 From: Andrew Burgess <andrew.burgess@embecosm.com> To: Don Breazeal <donb@codesourcery.com> Cc: gdb-patches@sourceware.org Subject: Re: [PATCH] Fix -var-update for registers in frames 1 and up Message-ID: <20160608130856.GD26734@embecosm.com> References: <1465335417-36881-1-git-send-email-donb@codesourcery.com> <20160608130051.GC26734@embecosm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20160608130051.GC26734@embecosm.com> X-Editor: GNU Emacs [ http://www.gnu.org/software/emacs ] User-Agent: Mutt/1.6.1 (2016-04-27) X-IsSubscribed: yes |
Commit Message
Andrew Burgess
June 8, 2016, 1:08 p.m. UTC
* Andrew Burgess <andrew.burgess@embecosm.com> [2016-06-08 14:00:51 +0100]: > * Don Breazeal <donb@codesourcery.com> [2016-06-07 14:36:57 -0700]: > > > This patch fixes a problem with using the MI -var-update command > > to access the values of registers in frames other than the current > > frame. The patch includes a test that demonstrates the problem: > > > > * run so there are several frames on the stack > > * create a varobj for $pc in each frame, #'s 1 and above > > * step one instruction, to modify the value of $pc > > * call -var-update for each of the previously created varobjs > > to verify that they are not reported as having changed. > > > > Without the patch, the -var-update command reported that $pc for all > > frames 1 and above had changed to the value of $pc in frame 0. > > > > The -var-create command takes a '--frame' argument and uses that > > to select the frame for retrieving the register value. But -var-update > > has no such argument, and previously didn't do anything to select the > > frame, so for frames other than frame 0 it returned the value of the > > register for frame 0, instead of reporting the value as unchanged. > > This shouldn't need special handling for register varobj values, if I > create a varobj watching value 'foo' in frame 1, but have a local > 'foo' in frame 0, a change in frame 0 'foo' will not trigger a change > for frame 1's 'foo' varobj. > > The magic is actually in varobj.c:check_scope, which makes use of the > varobj->root->frame to select the right frame based on the type of the > varobj, this is setup at varobj creation time. > > The problem, is that for register expressions the varobj->root->frame > is not set correctly. This frame tracking is done using the global > 'innermost_block' which is set in the various parser files (for > example c-exp.y), however, this is not set for register expressions. > I think that we probably should be doing this in > write_dollar_variable. Something like the following (untested): Thanks, Andrew
Comments
On 6/8/2016 6:08 AM, Andrew Burgess wrote: > * Andrew Burgess <andrew.burgess@embecosm.com> [2016-06-08 14:00:51 +0100]: > >> * Don Breazeal <donb@codesourcery.com> [2016-06-07 14:36:57 -0700]: >> >>> This patch fixes a problem with using the MI -var-update command >>> to access the values of registers in frames other than the current >>> frame. The patch includes a test that demonstrates the problem: >>> >>> * run so there are several frames on the stack >>> * create a varobj for $pc in each frame, #'s 1 and above >>> * step one instruction, to modify the value of $pc >>> * call -var-update for each of the previously created varobjs >>> to verify that they are not reported as having changed. >>> >>> Without the patch, the -var-update command reported that $pc for all >>> frames 1 and above had changed to the value of $pc in frame 0. >>> >>> The -var-create command takes a '--frame' argument and uses that >>> to select the frame for retrieving the register value. But -var-update >>> has no such argument, and previously didn't do anything to select the >>> frame, so for frames other than frame 0 it returned the value of the >>> register for frame 0, instead of reporting the value as unchanged. >> >> This shouldn't need special handling for register varobj values, if I >> create a varobj watching value 'foo' in frame 1, but have a local >> 'foo' in frame 0, a change in frame 0 'foo' will not trigger a change >> for frame 1's 'foo' varobj. >> >> The magic is actually in varobj.c:check_scope, which makes use of the >> varobj->root->frame to select the right frame based on the type of the >> varobj, this is setup at varobj creation time. >> >> The problem, is that for register expressions the varobj->root->frame >> is not set correctly. This frame tracking is done using the global >> 'innermost_block' which is set in the various parser files (for >> example c-exp.y), however, this is not set for register expressions. >> I think that we probably should be doing this in >> write_dollar_variable. Andrew, Thanks for explaining. I had followed innermost_block quite a bit in my debugging, but somehow convinced myself that wasn't the solution. > > Something like the following (untested): > > diff --git a/gdb/parse.c b/gdb/parse.c > index 2b00708..224c022 100644 > --- a/gdb/parse.c > +++ b/gdb/parse.c > @@ -705,6 +705,10 @@ handle_register: > str.ptr++; > write_exp_string (ps, str); > write_exp_elt_opcode (ps, OP_REGISTER); > + if (innermost_block == NULL > + || contained_in (expression_context_block, > + innermost_block)) > + innermost_block = expression_context_block; > return; > } Your solution works for both the fixed a floating varobj cases. I've extended my new test to cover the floating case. Unfortunately in the full test suite I've run into some unexpected side-effects that need further investigation. Hopefully an updated patch will be forthcoming soon. --Don
On 6/8/2016 5:48 PM, Breazeal, Don wrote: > On 6/8/2016 6:08 AM, Andrew Burgess wrote: >> * Andrew Burgess <andrew.burgess@embecosm.com> [2016-06-08 14:00:51 +0100]: >> >>> * Don Breazeal <donb@codesourcery.com> [2016-06-07 14:36:57 -0700]: >>> >>>> This patch fixes a problem with using the MI -var-update command >>>> to access the values of registers in frames other than the current >>>> frame. The patch includes a test that demonstrates the problem: >>>> >>>> * run so there are several frames on the stack >>>> * create a varobj for $pc in each frame, #'s 1 and above >>>> * step one instruction, to modify the value of $pc >>>> * call -var-update for each of the previously created varobjs >>>> to verify that they are not reported as having changed. >>>> >>>> Without the patch, the -var-update command reported that $pc for all >>>> frames 1 and above had changed to the value of $pc in frame 0. >>>> >>>> The -var-create command takes a '--frame' argument and uses that >>>> to select the frame for retrieving the register value. But -var-update >>>> has no such argument, and previously didn't do anything to select the >>>> frame, so for frames other than frame 0 it returned the value of the >>>> register for frame 0, instead of reporting the value as unchanged. >>> >>> This shouldn't need special handling for register varobj values, if I >>> create a varobj watching value 'foo' in frame 1, but have a local >>> 'foo' in frame 0, a change in frame 0 'foo' will not trigger a change >>> for frame 1's 'foo' varobj. >>> >>> The magic is actually in varobj.c:check_scope, which makes use of the >>> varobj->root->frame to select the right frame based on the type of the >>> varobj, this is setup at varobj creation time. >>> >>> The problem, is that for register expressions the varobj->root->frame >>> is not set correctly. This frame tracking is done using the global >>> 'innermost_block' which is set in the various parser files (for >>> example c-exp.y), however, this is not set for register expressions. >>> I think that we probably should be doing this in >>> write_dollar_variable. > > Andrew, > Thanks for explaining. I had followed innermost_block quite a bit > in my debugging, but somehow convinced myself that wasn't the solution. > >> >> Something like the following (untested): >> >> diff --git a/gdb/parse.c b/gdb/parse.c >> index 2b00708..224c022 100644 >> --- a/gdb/parse.c >> +++ b/gdb/parse.c >> @@ -705,6 +705,10 @@ handle_register: >> str.ptr++; >> write_exp_string (ps, str); >> write_exp_elt_opcode (ps, OP_REGISTER); >> + if (innermost_block == NULL >> + || contained_in (expression_context_block, >> + innermost_block)) >> + innermost_block = expression_context_block; >> return; >> } > > Your solution works for both the fixed a floating varobj cases. > I've extended my new test to cover the floating case. Unfortunately > in the full test suite I've run into some unexpected side-effects > that need further investigation. I haven't gone through all the failures, but I have found the cause of one of the side-effects of this change. In the CLI, the 'display' command depends on parsing a register expression to *not* set innermost_block. If the expression has a block, it has to be in-scope or display will skip it rather than evaluating the expression. See printcmd.c:do_one_display, the handling of d->block. It basically does: d->exp = parse_expression (d->exp_string); d->block = innermost_block; ---snip--- if (d->block) { if (d->pspace == current_program_space) within_current_scope = contained_in (get_selected_block (0), d->block); ---snip--- } else within_current_scope = 1; if (!within_current_scope) return; It seems like we will need a special case someplace. In do_one_display we could NULL out d->block for register expressions, or in varobj_update we could expand on the original patch to properly handle floating varobjs. Perhaps since the problem under consideration is only in MI, making the MI-specific change in varobj_update would minimize side-effects in the CLI. WDYT? I will continue investigating the failures to see if there is anything else there. thanks --Don
diff --git a/gdb/parse.c b/gdb/parse.c index 2b00708..224c022 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -705,6 +705,10 @@ handle_register: str.ptr++; write_exp_string (ps, str); write_exp_elt_opcode (ps, OP_REGISTER); + if (innermost_block == NULL + || contained_in (expression_context_block, + innermost_block)) + innermost_block = expression_context_block; return; }