From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from eggs.gnu.org (eggs.gnu.org [IPv6:2001:470:142:3::10]) by sourceware.org (Postfix) with ESMTPS id 9AF263861893 for ; Thu, 13 Aug 2020 13:31:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 9AF263861893 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=gnu.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=eliz@gnu.org Received: from fencepost.gnu.org ([2001:470:142:3::e]:54272) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1k6DKk-0003Eg-3Z; Thu, 13 Aug 2020 09:31:54 -0400 Received: from [176.228.60.248] (port=2449 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1k6DKj-0000H9-Jb; Thu, 13 Aug 2020 09:31:53 -0400 Date: Thu, 13 Aug 2020 16:31:46 +0300 Message-Id: <83bljen03h.fsf@gnu.org> From: Eli Zaretskii To: Andrew Burgess Cc: gdb-patches@sourceware.org In-Reply-To: <57329695b9a4a4bca9c5ef8c4a657ba9c6c1272d.1597319264.git.andrew.burgess@embecosm.com> (message from Andrew Burgess on Thu, 13 Aug 2020 13:58:45 +0100) Subject: Re: [PATCH 8/8] gdb/fortran: Add support for Fortran array slices at the GDB prompt References: <57329695b9a4a4bca9c5ef8c4a657ba9c6c1272d.1597319264.git.andrew.burgess@embecosm.com> X-Spam-Status: No, score=-4.0 required=5.0 tests=BAYES_00, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org 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: , X-List-Received-Date: Thu, 13 Aug 2020 13:31:56 -0000 > From: Andrew Burgess > Date: Thu, 13 Aug 2020 13:58:45 +0100 > > This commit brings array slice support to GDB. > > WARNING: This patch contains a rather big hack which is limited to > Fortran arrays, this can be seen in gdbtypes.c and f-lang.c. More > details on this below. > > This patch rewrites two areas of GDB's Fortran support, the code to > extract an array slice, and the code to print an array. > > After this commit a user can, from the GDB prompt, ask for a slice of > a Fortran array and should get the correct result back. Slices can > (optionally) have the lower bound, upper bound, and a stride > specified. Slices can also have a negative stride. > > Fortran has the concept of repacking array slices. Within a compiled > Fortran program if a user passes a non-contiguous array slice to a > function then the compiler may have to repack the slice, this involves > copying the elements of the slice to a new area of memory before the > call, and copying the elements back to the original array after the > call. Whether repacking occurs will depend on which version of > Fortran is being used, and what type of function is being called. > > This commit adds support for both packed, and unpacked array slicing, > with the default being unpacked. > > With an unpacked array slice, when the user asks for a slice of an > array GDB creates a new type that accurately describes where the > elements of the slice can be found within the original array, a > value of this type is then returned to the user. The address of an > element within the slice will be equal to the address of an element > within the original array. > > A user can choose to selected packed array slices instead using: > > (gdb) set fortran repack-array-slices on|off > (gdb) show fortran repack-array-slices > > With packed array slices GDB creates a new type that reflects how the > elements of the slice would look if they were laid out in contiguous > memory, allocates a value of this type, and then fetches the elements > from the original array and places then into the contents buffer of > the new value. > > One benefit of using packed slices over unapacked slices is the memory > usage, taking a small slice of N elements from a large array will > require (in GDB) N * ELEMENT_SIZE bytes of memory, while an unpacked > array will also include all of the "padding" between the > non-contiguous elements. There are new tests added that highlight > this difference. > > There is also a new debugging flag added with this commit that > introduces these commands: > > (gdb) set debug fortran-array-slicing on|off > (gdb) show debug fortran-array-slicing > > This prints information about how the array slices are being built. > > As both the repacking, and the array printing requires GDB to walk > through a multi-dimensional Fortran array visiting each element, this > commit adds the file f-array-walk.h, which introduces some > infrastructure to support this process. This means the array printing > code in f-valprint.c is significantly reduced. > > The only slight issue with this commit is the "rather big hack" that I > mentioned above. This hack allows us to handle one specific case, > array slices with negative strides. This is something that I don't > believe the current GDB value contents model will allow us to > "correctly" handle, and rather than rewrite the value contents code > right now, I'm hoping to slip this hack in as a work around. > > The problem is that as I see it the current value contents model > assumes that an object base address will be the lowest address within > that object, and that the contents of the object start at this base > address and occupy the TYPE_LENGTH bytes after that. > > We do have the embedded_offset, which is used for C++ sub-classes, > such that an object can start at some offset from the content buffer, > however, the assumption that the object then occupies the next > TYPE_LENGTH bytes is still true within GDB. > > The problem is that Fortran arrays with a negative stride don't follow > this pattern. In this case the base address of the object points to > the element with the highest address, the contents of the array then > start at some offset _before_ the base address, and proceed for one > element _past_ the base address. > > This is further complicated because arrays with negative strides like > this are always dynamic types, the program being debugged has passed a > slice with a negative stride to a function, and it is only when we > actually try to look at the slice within the function that the dynamic > type is resolved, and the negative type is seen. When dealing with > dynamic types like this the address is actually stored on the _type_, > not the value, this dynamic address then overrides the value's address > in the value_address function. > > I currently don't see any way to handle this address configuration > with GDB's current dynamic type and value system, which is why I've > added this hack: > > When we resolve a dynamic Fortran array type, if the stride is > negative, then we adjust the base address to point to the lowest > address required by the array. The printing and slicing code is aware > of this adjustment and will correctly slice and print Fortran arrays. > > Where this hack will show through to the user is if they ask for the > address of an array in their program with a negative array stride, the > address they get from GDB will not match the address that would be > computed within the Fortran program. > > gdb/ChangeLog: > > * Makefile.in (HFILES_NO_SRCDIR): Add f-array-walker.h. > * NEWS: Mention new options. > * expprint.c (dump_subexp_body_standard): Print RANGE_HAS_STRIDE. > * expression.h (enum range_type): Add RANGE_HAS_STRIDE. > * f-array-walker.h: New file. > * f-exp.y (arglist): Allow for a series of subranges. > (subrange): Add cases for subranges with strides. > * f-lang.c: Include 'gdbcmd.h' and 'f-array-walker.h'. > (repack_array_slices): New static global. > (show_repack_array_slices): New function. > (fortran_array_slicing_debug): New static global. > (show_fortran_array_slicing_debug): New function. > (value_f90_subarray): Delete. > (skip_undetermined_arglist): Delete. > (class fortran_array_repacker_base_impl): New class. > (class fortran_lazy_array_repacker_impl): New class. > (class fortran_array_repacker_impl): New class. > (fortran_value_subarray): Complete rewrite. > (set_fortran_list): New static global. > (show_fortran_list): Likewise. > (_initialize_f_language): Register new commands. > (fortran_adjust_dynamic_array_base_address_hack): New function. > * f-lang.h (fortran_adjust_dynamic_array_base_address_hack): > Declare. > * f-valprint.c: Include 'f-array-walker.h'. > (class fortran_array_printer_impl): New class. > (f77_print_array_1): Delete. > (f77_print_array): Delete. > (fortran_print_array): New. > (f_value_print_inner): Update to call fortran_print_array. > * gdbtypes.c: Include 'f-lang.h'. > (resolve_dynamic_type_internal): Call > fortran_adjust_dynamic_array_base_address_hack. > * parse.c (operator_length_standard): Handle RANGE_HAS_STRIDE. > > gdb/testsuite/ChangeLog: > > * gdb.fortran/array-slices-bad.exp: New file. > * gdb.fortran/array-slices-bad.f90: New file. > * gdb.fortran/array-slices-sub-slices.exp: New file. > * gdb.fortran/array-slices-sub-slices.f90: New file. > * gdb.fortran/array-slices.exp: Rewrite tests. > * gdb.fortran/array-slices.f90: Rewrite tests. > * gdb.fortran/vla-sizeof.exp: Correct expected results. > > gdb/doc/ChangeLog: > > * gdb.texinfo (Debugging Output): Document 'set/show debug > fotran-array-slicing'. > (Special Fortran Commands): Document 'set/show fortran > repack-array-slices'. Thanks, the documentation parts are okay.