View Issue Details

IDProjectCategoryView StatusLast Update
0036144FPCCompilerpublic2019-10-13 18:10
ReporterMartin FriebeAssigned ToJonas Maebe 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionreopened 
Platform64bit IntelOSwin 10OS Version10
Product Version3.3.1Product Build 
Target VersionFixed in Version3.3.1 
Summary0036144: Wrong Dwarf2/3/4 info for array (all array, but affects bitpacked) / incorrect use of DW_AT_bit_stride
Descriptionfor a type like
  TTinyRange = 0..5;
  TBitPackTinyArray = bitpacked array [0..3] of TTinyRange;

Fpc produces dwarf like

DW_TAG_array_type
  DW_AT_name, DW_FORM_string, 'TBitPackTinyNegArray'+#0
  DW_AT_byte_size, DW_FORM_udata, 2
  DW_AT_type, DW_FORM_ref4, ....
  DW_TAG_subrange_type;
    DW_AT_lower_bound, DW_FORM_sdata, 0
    DW_AT_upper_bound, DW_FORM_sdata, 3
    DW_AT_bit_stride, DW_FORM_udata, 3
    DW_AT_type, DW_FORM_ref4, ....

Note that the stride is in the DW_TAG_subrange_type

Dwarf 2 only allows for stride in DW_TAG_array_type, but not in the subrange at all

Dwarf 3/4 allow for stride in DW_TAG_array_type and DW_TAG_subrange_type
with the following description (from dwarf 4 spec, but same applies in dwarf 3 and 5)

DW_TAG_array_type
If the amount of storage allocated to hold each element of an object of the given array type is different from the amount of storage that is normally allocated to hold an individual object of the indicated element type, then the array type entry has either a DW_AT_byte_stride or a DW_AT_bit_stride attribute, whose value (see Section 2.19) is the size of each element of the array

DW_TAG_subrange_type
If the subrange type occurs as the description of a dimension of an array type, and the stride for that dimension is different than what would otherwise be determined, then the subrange type entry has either a DW_AT_byte_stride or DW_AT_bit_stride attribute which specifies the separation between successive elements along the dimension as described in Section 2.21..

That is a stride in the subrange specifies the amount of PADDING between element (most inner index) or between each sub-array (higher index).

However from the encoded data, fpc intends for the stride to overwrite the element default size.
For this the stride must be in the DW_TAG_array_type
This would then be ok for dwarf 2/3/4 and 5
TagsNo tags attached.
Fixed in Revision43171
FPCOldBugId
FPCTarget-
Attached Files
  • dwarf3_array_stride_location.diff (1,619 bytes)
    *** y:/Temp/mtmp/dbgdwarf.pas-revBASE.svn005.tmp.pas	Sat Oct 12 14:25:07 2019
    --- B:/FPC/SVN/trunk/compiler/dbgdwarf.pas	Sat Oct 12 21:56:55 2019
    ***************
    *** 4237,4249 ****
              if assigned(def.typesym) then
                append_entry(DW_TAG_array_type,true,[
                  DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
    !             DW_AT_data_location,DW_FORM_block1,2,
    !             DW_AT_byte_stride,DW_FORM_udata,def.elesize
                  ])
              else
                append_entry(DW_TAG_array_type,true,[
    !             DW_AT_data_location,DW_FORM_block1,2,
    !             DW_AT_byte_stride,DW_FORM_udata,def.elesize
                  ]);
              current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_push_object_address)));
              current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_deref)));
    --- 4237,4249 ----
              if assigned(def.typesym) then
                append_entry(DW_TAG_array_type,true,[
                  DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
    !             DW_AT_byte_stride,DW_FORM_udata,def.elesize,
    !             DW_AT_data_location,DW_FORM_block1,2
                  ])
              else
                append_entry(DW_TAG_array_type,true,[
    !             DW_AT_byte_stride,DW_FORM_udata,def.elesize,
    !             DW_AT_data_location,DW_FORM_block1,2
                  ]);
              current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_push_object_address)));
              current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_deref)));
    
  • dwarf3_array_stride_location_uni.diff (1,157 bytes)
    --- a/trunk/compiler/dbgdwarf.pas	Sat Oct 12 14:25:07 2019
    +++ b/trunk/compiler/dbgdwarf.pas	Sat Oct 12 21:56:55 2019
    @@ -4235,17 +4235,17 @@
               end;
     
             if assigned(def.typesym) then
               append_entry(DW_TAG_array_type,true,[
                 DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
    -            DW_AT_data_location,DW_FORM_block1,2,
    -            DW_AT_byte_stride,DW_FORM_udata,def.elesize
    +            DW_AT_byte_stride,DW_FORM_udata,def.elesize,
    +            DW_AT_data_location,DW_FORM_block1,2
                 ])
             else
               append_entry(DW_TAG_array_type,true,[
    -            DW_AT_data_location,DW_FORM_block1,2,
    -            DW_AT_byte_stride,DW_FORM_udata,def.elesize
    +            DW_AT_byte_stride,DW_FORM_udata,def.elesize,
    +            DW_AT_data_location,DW_FORM_block1,2
                 ]);
             current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_push_object_address)));
             current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_deref)));
     
             append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.elementdef));
    

Activities

Martin Friebe

2019-10-09 14:58

manager   ~0118447

Stride is written for all arrays. But the issue is noticeable when stride differs from the size of the element type. Which is true for bitpacked array. (Changed subject accordingly)

I assume that gdb does not actually use the stride from dimensions (otherwise it should skip every 2nd entry).
Having no stride in the actual array-def just means it uses the element size.

Also found this was introduced in
Revision: 13680
Author: joost
Date: 08 September 2009 19:00:55
Message: * Place stride in subrange-entry of array

Martin Friebe

2019-10-12 23:59

manager   ~0118534

This breaks the data_location.

The stride is inserted between the DW_AT_data_location and the DW_OP_... to calculate it. See attached patch.

About the path: This was the easiest way to fix it, but maybe it would be desired to have separate append_entry for better readability.

Martin Friebe

2019-10-12 23:59

manager  

dwarf3_array_stride_location.diff (1,619 bytes)
*** y:/Temp/mtmp/dbgdwarf.pas-revBASE.svn005.tmp.pas	Sat Oct 12 14:25:07 2019
--- B:/FPC/SVN/trunk/compiler/dbgdwarf.pas	Sat Oct 12 21:56:55 2019
***************
*** 4237,4249 ****
          if assigned(def.typesym) then
            append_entry(DW_TAG_array_type,true,[
              DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
!             DW_AT_data_location,DW_FORM_block1,2,
!             DW_AT_byte_stride,DW_FORM_udata,def.elesize
              ])
          else
            append_entry(DW_TAG_array_type,true,[
!             DW_AT_data_location,DW_FORM_block1,2,
!             DW_AT_byte_stride,DW_FORM_udata,def.elesize
              ]);
          current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_push_object_address)));
          current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_deref)));
--- 4237,4249 ----
          if assigned(def.typesym) then
            append_entry(DW_TAG_array_type,true,[
              DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
!             DW_AT_byte_stride,DW_FORM_udata,def.elesize,
!             DW_AT_data_location,DW_FORM_block1,2
              ])
          else
            append_entry(DW_TAG_array_type,true,[
!             DW_AT_byte_stride,DW_FORM_udata,def.elesize,
!             DW_AT_data_location,DW_FORM_block1,2
              ]);
          current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_push_object_address)));
          current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_deref)));

Cyrax

2019-10-13 01:33

reporter   ~0118535

Umm, Martin? Can you create a better patch? In your patch, it is a bit hard to see what is changed and where.

Martin Friebe

2019-10-13 02:00

manager   ~0118536

You are referring to the format of the "patch"? Or to its content (the proposed change)?

Assuming the former, I have attached it in unified format too

dwarf3_array_stride_location_uni.diff (1,157 bytes)
--- a/trunk/compiler/dbgdwarf.pas	Sat Oct 12 14:25:07 2019
+++ b/trunk/compiler/dbgdwarf.pas	Sat Oct 12 21:56:55 2019
@@ -4235,17 +4235,17 @@
           end;
 
         if assigned(def.typesym) then
           append_entry(DW_TAG_array_type,true,[
             DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
-            DW_AT_data_location,DW_FORM_block1,2,
-            DW_AT_byte_stride,DW_FORM_udata,def.elesize
+            DW_AT_byte_stride,DW_FORM_udata,def.elesize,
+            DW_AT_data_location,DW_FORM_block1,2
             ])
         else
           append_entry(DW_TAG_array_type,true,[
-            DW_AT_data_location,DW_FORM_block1,2,
-            DW_AT_byte_stride,DW_FORM_udata,def.elesize
+            DW_AT_byte_stride,DW_FORM_udata,def.elesize,
+            DW_AT_data_location,DW_FORM_block1,2
             ]);
         current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_push_object_address)));
         current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_deref)));
 
         append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.elementdef));

Cyrax

2019-10-13 03:25

reporter   ~0118537

Yes, the format. And thanks for the patch in the unified format.

Jonas Maebe

2019-10-13 09:38

manager   ~0118549

Sorry for breaking, and thanks for the patch.

Issue History

Date Modified Username Field Change
2019-10-07 23:02 Martin Friebe New Issue
2019-10-09 14:58 Martin Friebe Summary Wrong Dwarf2/3/4 info for "bitpacked array" / incorrect use of DW_AT_bit_stride => Wrong Dwarf2/3/4 info for array (all array, but affects bitpacked) / incorrect use of DW_AT_bit_stride
2019-10-09 14:58 Martin Friebe FPCTarget => -
2019-10-09 14:58 Martin Friebe Note Added: 0118447
2019-10-12 14:25 Jonas Maebe Assigned To => Jonas Maebe
2019-10-12 14:25 Jonas Maebe Status new => resolved
2019-10-12 14:25 Jonas Maebe Resolution open => fixed
2019-10-12 14:25 Jonas Maebe Fixed in Version => 3.3.1
2019-10-12 14:25 Jonas Maebe Fixed in Revision => 43171
2019-10-12 23:59 Martin Friebe Status resolved => feedback
2019-10-12 23:59 Martin Friebe Resolution fixed => reopened
2019-10-12 23:59 Martin Friebe Note Added: 0118534
2019-10-12 23:59 Martin Friebe File Added: dwarf3_array_stride_location.diff
2019-10-13 01:33 Cyrax Note Added: 0118535
2019-10-13 02:00 Martin Friebe File Added: dwarf3_array_stride_location_uni.diff
2019-10-13 02:00 Martin Friebe Note Added: 0118536
2019-10-13 02:00 Martin Friebe Status feedback => assigned
2019-10-13 03:25 Cyrax Note Added: 0118537
2019-10-13 09:38 Jonas Maebe Status assigned => resolved
2019-10-13 09:38 Jonas Maebe Note Added: 0118549
2019-10-13 18:10 Martin Friebe Status resolved => closed