From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id FIroCaDNp1/OSQAAWB0awg (envelope-from ) for ; Sun, 08 Nov 2020 05:51:12 -0500 Received: by simark.ca (Postfix, from userid 112) id 1BEE31F08B; Sun, 8 Nov 2020 05:51:12 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=MAILING_LIST_MULTI, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 2F1DC1E58F for ; Sun, 8 Nov 2020 05:51:11 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A89E03858012; Sun, 8 Nov 2020 10:51:10 +0000 (GMT) Received: from rock.gnat.com (rock.gnat.com [IPv6:2620:20:4000:0:a9e:1ff:fe9b:1d1]) by sourceware.org (Postfix) with ESMTP id 9DD3A3858012 for ; Sun, 8 Nov 2020 10:51:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 9DD3A3858012 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=brobecker@adacore.com Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 7D150117E2B; Sun, 8 Nov 2020 05:51:04 -0500 (EST) X-Virus-Scanned: Debian amavisd-new at gnat.com Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id Qol-NkE1sOLN; Sun, 8 Nov 2020 05:51:04 -0500 (EST) Received: from float.home (localhost.localdomain [127.0.0.1]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by rock.gnat.com (Postfix) with ESMTPS id 285AF117DFA; Sun, 8 Nov 2020 05:51:04 -0500 (EST) Received: by float.home (Postfix, from userid 1000) id 2184AA1882; Sun, 8 Nov 2020 14:50:59 +0400 (+04) Date: Sun, 8 Nov 2020 14:50:59 +0400 From: Joel Brobecker To: Andrew Burgess Subject: Re: [PATCH] gdb: user variables with components of dynamic type Message-ID: <20201108105059.GC451505@adacore.com> References: <20201022153238.1947197-1-andrew.burgess@embecosm.com> <20201106230422.GK2729@embecosm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20201106230422.GK2729@embecosm.com> X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gdb-patches@sourceware.org Errors-To: gdb-patches-bounces@sourceware.org Sender: "Gdb-patches" Hi Andrew, > * Andrew Burgess [2020-10-22 16:32:38 +0100]: > > > Consider this Fortran type: > > > > type :: some_type > > integer, allocatable :: array_one (:,:) > > integer :: a_field > > integer, allocatable :: array_two (:,:) > > end type some_type > > > > And a variable declared: > > > > type(some_type) :: some_var > > > > Now within GDB we try this: > > > > (gdb) set $a = some_var > > (gdb) p $a > > $1 = ( array_one = > > ../../src/gdb/value.c:3968: internal-error: Unexpected lazy value type. > > > > Normally, when an internalvar ($a in this case) is created, it is > > non-lazy, the value is immediately copied out of the inferior into > > GDB's memory. > > > > When printing the internalvar ($a) GDB will extract each field in > > turn, so in this case `array_one`. As the original internalvar is > > non-lazy then the extracted field will also be non-lazy, with its > > contents immediately copied from the parent internalvar. > > > > However, when the field has a dynamic type this is not the case, > > value_primitive_field we see that any field with dynamic type is > > always created lazy. Further, the content of this field will usually > > not have been captured in the contents buffer of the original value, a > > field with dynamic location is effectively a pointer value contained > > within the parent value, with rules in the DWARF for how to > > dereference the pointer. Is it a pointer, or a reference? From what you are seeing and what you are reported here, I assume these components are declared as references? Or perhaps, after written 3 different versions of a reply to this email, they are actually *neither*, but rather are described as arrays with location expressions? > > So, we end up with a lazy lval_internalvar_component representing a > > field within an lval_internalvar. This eventually ends up in > > value_fetch_lazy, which currently does not support > > lval_internalvar_component, and we see the error above. > > > > My original plan for how to handle this involved extending > > value_fetch_lazy to handle lval_internalvar_component. However, when > > I did this I ran into another error: > > > > (gdb) set $a = some_var > > (gdb) p $a > > $1 = ( array_one = ((1, 1) (1, 1) (1, 1)), a_field = 5, array_two = ((0, 0, 0) (0, 0, 0)) ) > > (gdb) p $a%array_one > > $2 = ((1, 1) (1, 1) (1, 1)) > > (gdb) p $a%array_one(1,1) > > ../../src/gdb/value.c:1547: internal-error: void set_value_address(value*, CORE_ADDR): Assertion `value->lval == lval_memory' failed. I am not surprised. Intuitively, like you said, we expect GDB to "capture" the value of our variable, so we should have anything lazy about it, or else this would indicate an incomplete capture. > In an ideal world (I think) GDB would be > > able to do this even for values with dynamic type. So in our above > > example doing `set $a = some_var` would capture the content of > > 'some_var', but also the content of 'array_one', and also > > 'array_two', even these content regions are not contained within the > > region of 'some_var'. This would be my understanding as well, provided the arrays are *references*. For pointers, I think it's fine to continue with the idea that we capture the target address, but not the target memory region it points to. > > Supporting this would require GDB values to be able to carry around > > multiple non-contiguous regions of memory at content in some way, > > which sounds like a pretty huge change to a core part of GDB. > > > > So, I wondered if there was some other solution that wouldn't require > > such a huge change. > > > > What if values with a dynamic location were though of like points with > > automatic dereferencing? Given this C structure: > > > > struct foo_t { > > int *val; > > } > > > > struct foo_t my_foo; > > > > Then in GDB: > > > > (gdb) $a = my_foo > > > > We would expect GDB to capture the pointer value in '$a', but not the > > value pointed at by the pointer. So maybe it's not that unreasonable > > to think that given a dynamically typed field GDB will capture the > > address of the content, but not the actual content itself. > > > > That's what this patch does. I admit I don't really understand quite how this is all happening, and how you're trying to deal with the issue. It's possible that the compromise you suggest (treat dynamic components the same as pointers) might be the most reasonable way out, but I think it'll invite confusion on the users' side, and probably bug reports. At the very least, I think we should warn users when we do this, so as to be sure to set expectations right, on the spot. Have you looked at how we handle components which are references? I wonder how well we handle those... -- Joel