Message ID | 1477557571-17122-1-git-send-email-yao.qi@linaro.org |
---|---|
State | New, archived |
Headers |
Received: (qmail 4759 invoked by alias); 27 Oct 2016 08:39:48 -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 4712 invoked by uid 89); 27 Oct 2016 08:39:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=2016-10-27 X-HELO: mail-pf0-f193.google.com Received: from mail-pf0-f193.google.com (HELO mail-pf0-f193.google.com) (209.85.192.193) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 27 Oct 2016 08:39:37 +0000 Received: by mail-pf0-f193.google.com with SMTP id s8so2002795pfj.2 for <gdb-patches@sourceware.org>; Thu, 27 Oct 2016 01:39:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id; bh=bl3HWh9PG2cv9kxJqyunH7jfDMACXHuIhkAIqSdRZ6M=; b=Eqt5YXQGcLfYN0maK7TIzNH4KjawxE339Kn1EvE7siKzlczphGairaXhK/TaM+czrY Rr6wN1UhL5A6fzGt53Q5rOJJZMPwspeQOOhVWxdc5KhrVWcuUoKL5AmEelD/DfopO5Rr qg4olSjdx/WUxNViPThwA3k7y0aC50uduV6ZCB3BAXdjWZmzoI47TFo9mtYYBiU7huRv UVVj9gM06PxOKePAbc01a00b3mKRGYyDCq1opCyCRWc7ozxq4lUJSZGFi5h4L7JCQ2NL NQ8cFNY8W0pG7VJNVOTzGa0duJskzNLyKS+GBzZ5HeoSyjccY+Ak6PxHtaX1tAjxZUD1 8L5g== X-Gm-Message-State: ABUngvcNnwksfmUF7sg28fhPyRqaz5+fZJZt3uEpgl7iFKu02lw+73Vv99ELqIZ49weqWA== X-Received: by 10.98.0.198 with SMTP id 189mr12508959pfa.75.1477557575953; Thu, 27 Oct 2016 01:39:35 -0700 (PDT) Received: from E107787-LIN.cambridge.arm.com (gcc1-power7.osuosl.org. [140.211.15.137]) by smtp.gmail.com with ESMTPSA id 3sm9676145pam.21.2016.10.27.01.39.34 for <gdb-patches@sourceware.org> (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 27 Oct 2016 01:39:35 -0700 (PDT) From: Yao Qi <qiyaoltc@gmail.com> X-Google-Original-From: Yao Qi <yao.qi@linaro.org> To: gdb-patches@sourceware.org Subject: [PATCH] New function value_has_address Date: Thu, 27 Oct 2016 09:39:31 +0100 Message-Id: <1477557571-17122-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes |
Commit Message
Yao Qi
Oct. 27, 2016, 8:39 a.m. UTC
This patch is to move duplicated condition checking in three functions to a single new function, value_has_address. The patch is obvious. I'll push it in later today, in case that people think function value_has_address is not named properly. gdb: 2016-10-27 Yao Qi <yao.qi@linaro.org> * value.c (value_has_address): New function. (value_address): Call value_has_address. (value_raw_address): Likewise. (set_value_address): Likewise. --- gdb/value.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
Comments
That help clarifies the code, I like it. > diff --git a/gdb/value.c b/gdb/value.c > index b825aec..4b5cbde 100644 > --- a/gdb/value.c > +++ b/gdb/value.c > @@ -1538,12 +1538,20 @@ value_lval_const (const struct value *value) > return value->lval; > } > > +/* Return true if VALUE has address, otherwise return false. */ This comment is really obvious, it's really just stating the function name. Could you expand it a bit, perhaps saying what it means for a value to "have address"? I suppose it means that it has a memory address on the target?
On Thu, Oct 27, 2016 at 12:29 PM, Simon Marchi <simon.marchi@polymtl.ca> wrote: > That help clarifies the code, I like it. > >> diff --git a/gdb/value.c b/gdb/value.c >> index b825aec..4b5cbde 100644 >> --- a/gdb/value.c >> +++ b/gdb/value.c >> @@ -1538,12 +1538,20 @@ value_lval_const (const struct value *value) >> return value->lval; >> } >> >> +/* Return true if VALUE has address, otherwise return false. */ > > > This comment is really obvious, it's really just stating the function name. > Could you expand it a bit, perhaps saying what it means for a value to "have > address"? I suppose it means that it has a memory address on the target? It is intended to avoid expanding the comments because I can't give a clear meaning, like "has a memory address on the target", unless I fully understand "value" in gdb. That is why I only make value_has_address static. I find some inconsistencies across the code, /* The only lval kinds which do not live in target memory. */ if (VALUE_LVAL (val) != not_lval && VALUE_LVAL (val) != lval_internalvar && VALUE_LVAL (val) != lval_xcallable) return 0; lval_internalvar_component is not checked, /* set_value_component_location resets the address, so we may need to set it again. */ if (VALUE_LVAL (value) != lval_internalvar && VALUE_LVAL (value) != lval_internalvar_component && VALUE_LVAL (value) != lval_computed) set_value_address (value, address + embedded_offset); lval_xcallable is not checked, but lval_computed is checked. Before we clearly document the meaning of value_has_address, we need to figure out these things above first.
On 10/27/2016 01:12 PM, Yao Qi wrote: > On Thu, Oct 27, 2016 at 12:29 PM, Simon Marchi <simon.marchi@polymtl.ca> wrote: >> That help clarifies the code, I like it. >> >>> diff --git a/gdb/value.c b/gdb/value.c >>> index b825aec..4b5cbde 100644 >>> --- a/gdb/value.c >>> +++ b/gdb/value.c >>> @@ -1538,12 +1538,20 @@ value_lval_const (const struct value *value) >>> return value->lval; >>> } >>> >>> +/* Return true if VALUE has address, otherwise return false. */ >> >> >> This comment is really obvious, it's really just stating the function name. >> Could you expand it a bit, perhaps saying what it means for a value to "have >> address"? I suppose it means that it has a memory address on the target? > > It is intended to avoid expanding the comments because I can't give a > clear meaning, like "has a memory address on the target", unless I fully > understand "value" in gdb. That is why I only make value_has_address > static. > > I find some inconsistencies across the code, > > /* The only lval kinds which do not live in target memory. */ > if (VALUE_LVAL (val) != not_lval > && VALUE_LVAL (val) != lval_internalvar > && VALUE_LVAL (val) != lval_xcallable) > return 0; > > lval_internalvar_component is not checked, > > /* set_value_component_location resets the address, so we may > need to set it again. */ > if (VALUE_LVAL (value) != lval_internalvar > && VALUE_LVAL (value) != lval_internalvar_component > && VALUE_LVAL (value) != lval_computed) > set_value_address (value, address + embedded_offset); > > lval_xcallable is not checked, but lval_computed is checked. Before > we clearly document the meaning of value_has_address, we need to > figure out these things above first. > I think the answer is here: /* Location of value (if lval). */ union { /* If lval == lval_memory, this is the address in the inferior. If lval == lval_register, this is the byte offset into the registers structure. */ CORE_ADDR address; /* Pointer to internal variable. */ struct internalvar *internalvar; /* Pointer to xmethod worker. */ struct xmethod_worker *xm_worker; /* If lval == lval_computed, this is a set of function pointers to use to access and describe the value, and a closure pointer for them to use. */ struct { /* Functions to call. */ const struct lval_funcs *funcs; /* Closure for those functions to use. */ void *closure; } computed; } location; That's a union. We should only ever access the "address" on lval types that use the "address" field above. Note that we call value_address on lval_computed values and that incorrectly returns "value->location.address + value->offset", which is completely bogus. (Try running to main, and then doing p $_siginfo). The value printing routines want to pass around a value address, but since we actually pass the value pointer around nowadays too, I think that parameter could be eliminated, and the result is likely to be that value_address ends up called is much fewer places where it doesn't really make sense. IMO, struct value and its lval types would be nice candidates for converting to a class hierarchy, with lval_funcs expanded into virtual methods in struct value directly, that are then used by all value lval types, including lval_memory/lval_register. Thanks, Pedro Alves
On Thu, Oct 27, 2016 at 2:03 PM, Pedro Alves <palves@redhat.com> wrote: > > I think the answer is here: > > /* Location of value (if lval). */ > union > { > /* If lval == lval_memory, this is the address in the inferior. > If lval == lval_register, this is the byte offset into the > registers structure. */ > CORE_ADDR address; > > /* Pointer to internal variable. */ > struct internalvar *internalvar; > > /* Pointer to xmethod worker. */ > struct xmethod_worker *xm_worker; > > /* If lval == lval_computed, this is a set of function pointers > to use to access and describe the value, and a closure pointer > for them to use. */ > struct > { > /* Functions to call. */ > const struct lval_funcs *funcs; > > /* Closure for those functions to use. */ > void *closure; > } computed; > } location; > > > That's a union. We should only ever access the "address" > on lval types that use the "address" field above. So looks we can restrict value_has_address, /* Return true if VALUE->location.address is valid, otherwise return false. */ static int value_has_address (const struct value *value) { return (value->lval == lval_memory || value->lval == lval_register); } This triggers some GDB internal errors. I fixed some of them, but still don't know how to fix one in gdbpy_apply_val_pretty_printer, set_value_component_location (value, val); /* set_value_component_location resets the address, so we may need to set it again. */ if (VALUE_LVAL (value) != lval_internalvar && VALUE_LVAL (value) != lval_internalvar_component && VALUE_LVAL (value) != lval_computed) set_value_address (value, address + embedded_offset); still can't figure out why do we call set_value_component_location here. These code was added in https://sourceware.org/ml/gdb-patches/2010-06/msg00132.html I'll ask Tom. > > Note that we call value_address on lval_computed values and that > incorrectly returns "value->location.address + value->offset", > which is completely bogus. (Try running to main, and then doing > p $_siginfo). > > The value printing routines want to pass around a value address, > but since we actually pass the value pointer around nowadays too, > I think that parameter could be eliminated, and the result is > likely to be that value_address ends up called is much fewer > places where it doesn't really make sense. value_address () return value is not always passed to val_print. We pass zero to val_print in some places in ada-valprint.c. I don't see how to eliminate tat parameter, if I understand you correctly. > > IMO, struct value and its lval types would be nice candidates > for converting to a class hierarchy, with lval_funcs > expanded into virtual methods in struct value directly, that are > then used by all value lval types, including lval_memory/lval_register. > Yes, I agree, but I don't know how much memory usage increase if "struct value" becomes "class value". We have such comments to "struct value", /* Note that the fields in this structure are arranged to save a bit of memory. */ I am not ready converting value to C++ as I still don't think I fully understand it.
On 10/28/2016 12:49 PM, Yao Qi wrote: >> > IMO, struct value and its lval types would be nice candidates >> > for converting to a class hierarchy, with lval_funcs >> > expanded into virtual methods in struct value directly, that are >> > then used by all value lval types, including lval_memory/lval_register. >> > > Yes, I agree, but I don't know how much memory usage increase > if "struct value" becomes "class value". Maybe one pointer. Probably doesn't matter. It'd be the equivalent of moving the const struct lval_funcs *funcs field out of the union (If you add virtual methods to a class, it adds one hidden pointer to a table of function pointers -- the vtable, so that calls to virtual methods can dynamically dispatch, just like lval_funcs). If some fields move to subclasses that are seldom instantiated, then you may actually save memory. Or not, because the heap may already be returning memory blocks larger than we ask it, and we might simply waste less. Depends on current size of the structure, and malloc being used, etc. Not a clear cut. > We have such comments to "struct value", > > /* Note that the fields in this structure are arranged to save a bit > of memory. */ I think that's referring to the maybe-surprising ordering of members of the struct -- they're layed out to avoid holes due to alignment. > > I am not ready converting value to C++ as I still don't think I fully > understand it. I wasn't suggesting you'd do it yourself. Just saying that if people want to try it, they have my support. :-) Thanks, Pedro Alves
On 10/28/2016 12:49 PM, Yao Qi wrote: > >> > >> > Note that we call value_address on lval_computed values and that >> > incorrectly returns "value->location.address + value->offset", >> > which is completely bogus. (Try running to main, and then doing >> > p $_siginfo). >> > >> > The value printing routines want to pass around a value address, >> > but since we actually pass the value pointer around nowadays too, >> > I think that parameter could be eliminated, and the result is >> > likely to be that value_address ends up called is much fewer >> > places where it doesn't really make sense. > value_address () return value is not always passed to val_print. > We pass zero to val_print in some places in ada-valprint.c. > I don't see how to eliminate tat parameter, if I understand you > correctly. > That suggests that it's calling val_print on values that can't even have an address. Those cases would be adjusted to address, as the others. Then at the points that actually do need a value's address somewhere inside val_print and callees, we'd get the address from the struct value * pointer passed around as well, maybe adjusted with the sliding embedded_offset passed down too. Currently, it's not easy to see which are those places exactly because we always pass around some address, even if bogus. Thanks, Pedro Alves
diff --git a/gdb/value.c b/gdb/value.c index b825aec..4b5cbde 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -1538,12 +1538,20 @@ value_lval_const (const struct value *value) return value->lval; } +/* Return true if VALUE has address, otherwise return false. */ + +static int +value_has_address (const struct value *value) +{ + return (value->lval != lval_internalvar + && value->lval != lval_internalvar_component + && value->lval != lval_xcallable); +} + CORE_ADDR value_address (const struct value *value) { - if (value->lval == lval_internalvar - || value->lval == lval_internalvar_component - || value->lval == lval_xcallable) + if (!value_has_address (value)) return 0; if (value->parent != NULL) return value_address (value->parent) + value->offset; @@ -1559,9 +1567,7 @@ value_address (const struct value *value) CORE_ADDR value_raw_address (const struct value *value) { - if (value->lval == lval_internalvar - || value->lval == lval_internalvar_component - || value->lval == lval_xcallable) + if (!value_has_address (value)) return 0; return value->location.address; } @@ -1569,9 +1575,7 @@ value_raw_address (const struct value *value) void set_value_address (struct value *value, CORE_ADDR addr) { - gdb_assert (value->lval != lval_internalvar - && value->lval != lval_internalvar_component - && value->lval != lval_xcallable); + gdb_assert (value_has_address (value)); value->location.address = addr; }