See below to an answer on the issue.
Just a note on the reason for this.
I plan to keep the gdb based debugger in Lazarus even if the gdb free one will be all finished. The gdb based one supports more targets, and offers gdb server.
* In the gdb free debugger, I can look at the dwarf producer, and use the knowledge I have to handle any type, as what it means in pascal, independent of the dwarf description. This is not the favourite solution. But possible.
* In the gdb based version I can not do that. (I know no gdb command to get the producer. I simple have to assume it all was done by fpc, and fix all that can be fixed.
Indeed there is a workaround that can be applied, but it would mean extra slowdown, as additional ptype must first be sent to gdb to find out, if it an dynarray = otherdyn.
On the other hand, gdb is not yet dwarf3 ready, and if dwarf3 means that much extra maintenance, I may just not support it via gdb.
Well at this time, it is not clear, if it actually would be added to the gdb based version at all, even if all was fixed. It is just keeping an option open.
--------
What is the advantage for fpc to use DW_AT_data_location for dyn array?
IIRC the same discussion was once done for TObject, but I do not remember the outcome
--------------
Jonas Maebe wrote 22 lines
On 06 May 2014, at 01:29, Martin Frb wrote:
> When FPC generates dwarf 3, it does use DW_AT_data_location for
> dynamic array.
>
> That leads to gdb reporting "a=b" to be false, after the below code.
> (with dwarf 2 gdb compares the pointer, and returns true)
>
> var a,b: array of Integer;
> SetLength(a,3);
> b:=a;
>
> With that gdb does no longer know there is a hidden pointer.
>
> All GDB sees, is that a is at addr x, and b at addr y.
> It does not have a data size, or type for what is at that address.
>
> How to use that address is now hidden in the location expression in
> DW_AT_data_location.
Maybe @a and @b?
@a and @b are the addresses of the variable containing the pointer (@a)^ is ont the first member of the array, but the pointer to it.
I do not know if gdb does that correctly.
What gdb surprisingly does is
pointer(a)
I wonder though, if it (incorrectly) allows that for all types with DW_AT_data_location, or if it does in deep analysis of the location expression.
After all:
- if "a" is at $500000 and has a 4 or 8 byte pointer to $600000 where the array is
- Then the dwarf by fpc, only says there is
is no info in the dwarf that says if there is 1, 2 , or more bytes, or even 0 bytes.
The array type itself (see below) does not have a size. If you do not look at the DW_AT_data_location then you ca not tell there is a pointer.
It could be that the first few bytes are the length, and that DW_AT_data_location does NOT deref, but only add 4 bytes to the address to get to the data.
That is to know if there is a pointer, you have to analyse DW_AT_data_location. But DW_AT_data_location is not meant to describe the type, but only the data location
DW_TAG_array_type;
DW_AT_name, DW_FORM_string, 'TArrayDynInt'+#0
DW_AT_data_location, DW_FORM_block1, [$02, $97, $06] DW_AT_type, DW_FORM_ref4, @TypeDeclLongInt_635 // points to integer
DW_TAG_subrange_type;
DW_AT_byte_stride, DW_FORM_udata, 4);
DW_AT_lower_bound, DW_FORM_udata, 0);
DW_AT_upper_bound, DW_FORM_block1, BytesLen1([$97, $06, $12, $28,
$05, $00, $09, $FF, $2F, $03, $00, $34, $1C, $06]));
DW_AT_type, DW_FORM_ref4, @TypeDeclLongInt_635); // $21, $33, $00, $00
You need the location description for the upper bound (including nil check), but that should also work, if there was a pointer first? It would just have to skip the deref, as DW_OP_push_object_address should now refer to the derefed address (though, I have no idea, if GDB would deal with this. So that would need to be tested)