Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2014-05

dvarf 3 implementation issue

6 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Martin Frb

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.

Reply by email

Jonas Maebe
to Martin Frb
Martin Frb wrote 17 lines
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?

Jonas

Reply by email

Martin Frb
to Jonas Maebe

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)

Reply by email

Jonas Maebe
to Martin Frb
Martin Frb wrote
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.

I understand it's annoying, but I don't see a good solution.

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.

Actually, gdb even already supports most of DWARFv4 (and gcc generates it too). variable-length-array support was only merged to gdb master/trunk recently though, which is required for this FPC dynamic array support in the debugging information.

Show quoted text 6 lines
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?

It's to be able to describe dynamic arrays as actual arrays instead of as pointers in the debug information, so that debuggers don't have to know about FPC internals to determine that these pointers are actually arrays and to find out what their length is..

Jonas

Reply by email

Martin Frb
to Jonas Maebe
Jonas Maebe wrote 6 lines
On 08/05/14 16:10, Martin Frb wrote: > 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. I understand it's annoying, but I don't see a good solution.

What was wrong with the old pointer to array?

Even if coding in pascal, the fact that dyn arrays are pointers is exposed in various situations.

Show quoted text 8 lines
> 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. Actually, gdb even already supports most of DWARFv4 (and gcc generates it too). variable-length-array support was only merged to gdb master/trunk recently though, which is required for this FPC dynamic array support in the debugging information.

Yes it supports it, but it lacks testing with none gcc generated dwarf.

Well the latest I currently have for testing is 7.6.1, and that still crashes on various bits of dwarf by fpc. (including dwarf2, but iirc even worse with dwarf3)
Yes, I now, I ought to report them to the gdb bug tracker...

Show quoted text 12 lines
> 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? It's to be able to describe dynamic arrays as actual arrays instead of as pointers in the debug information, so that debuggers don't have to know about FPC internals to determine that these pointers are actually arrays and to find out what their length is..

Put they are pointers

- They can be assigned nil
- they can be typecast to pointer or ptrUint (try that with a static array)
- dynarr1-dynarr2 compares the pointers (again that differs from static array, that is not pointer based an behaves different)

So the entire point is, the debugger should know that they are pointers.

Hidding this from the debugger gets wrong results.

And it only means that if you want right results, the debugger now know other parts about how fpc dyn arrays really work. I dont see how that is better.

determine that these pointers are actually arrays and to find out what their length is..

I do not know about GDB, but from my reading of dwarf 3 the location expression (if the deref is taken out), should work with pointer to array to.

It actually depends, on what gdb will do with DW_OP_push_object_address in a location-expression for the subrange (representing the index).

- The object address should be the array (so the pointer should already have been applied.
- But if GDB uses the address before the pointer, then the deref must be kept.

It only is a problem if gdb does not implement
gdb allows to typecast it as anything.

e.g byte(somedynarray) / which fpc does not (gdb even does that for a static array). I ASSUME gdb just takes the address, and reds the new type from that address.
So that would explain why at least even with dwarf3, one can typecast the array to a pointer.

Reply by email

Martin Frb
to Martin Frb
Martin Frb wrote
So the entire point is, the debugger should know that they are pointers. Hidding this from the debugger gets wrong results.

Besides that GDB fails on those anyway (at least the gdb I have). Here is another one, that does not (and can not) work with the current expression location in gw3

program dyarr;
type
  TX=array of integer;
var
   a: TX;
   p: PtrUint;
begin
   SetLength(a,3);
   a[0] :=  1; a[1] :=  2; a[2] :=  3;
   p := ptruint(a)-4;
   writeln( TX(p+4)[1] ); //writes 2
end.

-data-evaluate-expression TX(p+4)

DW_AT_data_location starts with DW_OP_push_object_address

It needs the address of the variable. But "p+4" has no address.

A debugger could still use it as a pointer, so the dwarf 2 definition could work (as I said, I got trash in gdb with either dwarf / but the problems of gdb are not the point)

The new dwarf3 does simple not describe the type dyn-array

yet, if the type was pointer to array, then the important location expression for the array upper bound could still be added to the subrange definition. It would use a DW_OP_push_object_address too, but that would then refer to the array after the pointer was already resolved (at least it should)

Reply by email