Message ID | 20160825170626.GA29717@host1.jankratochvil.net |
---|---|
State | New |
Headers | show |
On Thu, 25 Aug 2016 19:06:26 +0200, Jan Kratochvil wrote:
> I have attached a fix.
That fix has a regression for normal (64-bit) inferiors.
I see the source handles negative stide specially. Particularly the comment
here does not explain the code it comments:
/* Adjust the data location with the value of byte stride if set, which
can describe the separation between successive elements along the
dimension. */
if (TYPE_BYTE_STRIDE (range_type) < 0)
value += (TYPE_HIGH_BOUND (range_type) - TYPE_LOW_BOUND (range_type))
* TYPE_BYTE_STRIDE (range_type);
else if (elt_stride < 0)
{
int offs = (elt_offs + 1) * elt_stride;
elt_offs = TYPE_LENGTH (array_type) + offs;
}
But I do not negative stride values described in DWARF-4 anyhow. When it is
used? With this interpretation of stride the gfortran random(?) stride value
for arrays with single row would be really wrong. But I do not see
a definition of negative stride in DWARF.
Thanks,
Jan
On 25/08/2016 19:06, Jan Kratochvil wrote: > On Tue, 23 Aug 2016 15:34:09 +0200, Bernhard Heckel wrote: >> created a branch with all stride patches. > users/bheckel/fortran-strides > 2c392d41a3f2e38deeb9db5b7a93ca45682bbe3b > >> I don't see regression on RH7.1, gcc 4.8.3-9 > I see a regression for 32-bit targets (x86_64-m32 or native i686) > on Fedora 24 (gcc-gfortran-6.1.1-3.fc24.x86_64). I do not see the regression > on CentOS-7.2 (x86_64-m32). > > print pvla^M > value requires 4294967288 bytes, which is more than max-value-size^M > (gdb) FAIL: gdb.fortran/vla-stride.exp: print single-element > > I have attached a fix. > > It is because: > <115> DW_AT_lower_bound : 4 byte block: 97 23 10 6 (DW_OP_push_object_address; DW_OP_plus_uconst: 16; DW_OP_deref) > <11a> DW_AT_upper_bound : 4 byte block: 97 23 14 6 (DW_OP_push_object_address; DW_OP_plus_uconst: 20; DW_OP_deref) > <11f> DW_AT_byte_stride : 6 byte block: 97 23 c 6 34 1e (DW_OP_push_object_address; DW_OP_plus_uconst: 12; DW_OP_deref; DW_OP_lit4; DW_OP_mul) > DW_AT_lower_bound == 1 > DW_AT_upper_bound == 1 > DW_AT_byte_stride == (-2) * 4 == -8 > > I am not sure if gfortran is really wrong or not but a stride does not make > sense for me for a single row array. > > Attaching also gdb.fortran/vla-stride.f90 from your branch built with > gcc-gfortran-6.1.1-3.fc24.x86_64 on Fedora 24 x86_64 in -m32 mode. > > Besides that I see on all archs > -FAIL: gdb.pascal/arrays.exp: Print dynamic array of string > +FAIL: gdb.pascal/arrays.exp: Print dynamic array of string (GDB internal error) > but that testcase is only in Fedora and the Pascal (fpc) support has been not > well maintained so far so I am OK with that. > > > Thanks, > Jan Hi Jan, found the root cause of the issue on 32bit inferior. According to DWARF4 (Page 100) strides can be negative but evaluation of dynamic properties in GDB is done via CORE_ADDR which is unsigned. This causes the issue that the type length seems to be way to big. The following code is not claimed to be a fix, just want to point you to the right direction. In gdbtypes.c: prop = &TYPE_RANGE_DATA (dyn_range_type)->stride; if (dwarf2_evaluate_property (prop, NULL, addr_stack, &value)) { /* if target is 32bit, execute next if clause */ if (value > (2^31)) value += 2^32; stride.kind = PROP_CONST; stride.data.const_val = value; } Also, in dwarf2read.c all DW_AT_...STRIDE 's are handles as unsigned. This has to be fixed as well. I will investigate more on the stride topic next week. Intel Deutschland GmbH Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany Tel: +49 89 99 8853-0, www.intel.de Managing Directors: Christin Eisenschmid, Christian Lamprechter Chairperson of the Supervisory Board: Nicole Lau Registered Office: Munich Commercial Register: Amtsgericht Muenchen HRB 186928
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 88801ac..1fbf69a 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -1103,10 +1103,12 @@ create_array_type_with_stride (struct type *result_type, if (high_bound < low_bound) TYPE_LENGTH (result_type) = 0; else if (byte_stride > 0) - TYPE_LENGTH (result_type) = byte_stride * (high_bound - low_bound + 1); + TYPE_LENGTH (result_type) = (byte_stride * (high_bound - low_bound) + + TYPE_LENGTH (element_type)); else if (bit_stride > 0) TYPE_LENGTH (result_type) = - (bit_stride * (high_bound - low_bound + 1) + 7) / 8; + ((bit_stride * (high_bound - low_bound) + 7) / 8 + + TYPE_LENGTH (element_type)); else TYPE_LENGTH (result_type) = TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);