[fpc-devel] Before 3.4 gets on the road, can anyone help with fpc Dwarf-properties extension (started by Joost)

Martin Frb lazarus at mfriebe.de
Tue Jul 4 14:54:36 CEST 2023


Currently the debugger can not show properties (even though it can call 
functions).

DWARF does not know properties, but custom tags can be added. Joost 
started this  in the branch fork-gl/joost/dwarfproperties
https://gitlab.com/freepascal.org/fpc/source/-/tree/joost/dwarfproperties

Rebased at 
https://gitlab.com/martin_frb/fpc-src/-/commits/joost-dwarfproperties
I started on reading that info: 
https://gitlab.com/martin_frb/lazarus/-/commits/fpdebug-godwarfproperties

See bottom of the mail for Joost's original explanation.
------------------------------------

Unfortunately I can't reach Joost.
And I really want that to be in 3.4 (whenever that will be).

Yet there are some issues (I am still testing, just what I found so far)

*** Issue 1)
Sometimes nhe references to the function/member are wrong.
I reproduced with a small test  (attached) -gw3 -godwarfproperties

In unit 1, all location for the getters are correct.
getter PropGetter at: 0x13c5
getter PropGetter2 at: 0x142f  (0x6a bytes higher)

In dwarf_prop_test.lpr the first property has the correct location for 
the getter.

But then the next property does not.
getter PropGetter at: 0x04b8
getter PropGetter2 at: 0x0522 (wrong, but also 0x6a bytes higher)

The actual GetPropGetter2 is at 4dd (only 0x25 bytes higher)

So somehow a value from the other unit was used? Or maybe this is 
because the address (low_pc) was omitted in the getter before, but the 
size for it was still added to the offset for the next getter?

In unit1
  <1><134e>: Abbrev Number: 4 (DW_TAG_class_type)
....
  <2><1381>: Abbrev Number: 7 (Unknown TAG value: 4230)
     <1382>   DW_AT_name        : PropGetter
     <138d>   Unknown AT value: 3230: <0x13c5>
  <2><1391>: Abbrev Number: 7 (Unknown TAG value: 4230)
     <1392>   DW_AT_name        : PropGetter2
     <139e>   Unknown AT value: 3230: <0x142f>

in dwarf_prop_test.lpr
  <1><441>: Abbrev Number: 5 (DW_TAG_class_type)
...
  <2><474>: Abbrev Number: 8 (Unknown TAG value: 4230)
     <475>   DW_AT_name        : PropGetter
     <480>   Unknown AT value: 3230: <0x4b8>
  <2><484>: Abbrev Number: 8 (Unknown TAG value: 4230)
     <485>   DW_AT_name        : PropGetter2
     <491>   Unknown AT value: 3230: <0x522>
...
  <2><4b8>: Abbrev Number: 14 (DW_TAG_subprogram)
     <4b9>   DW_AT_name        : GetPropGetter
...
  <2><4dd>: Abbrev Number: 14 (DW_TAG_subprogram)
     <4de>   DW_AT_name        : GetPropGetter2


*** Issue 2:
Nothing to do with Joosts code, but on Windows the entry pc for the 
methods aren't in the DWARF.

Well, the class is copied into each unit (on Linux there is a cross 
compile-units reference).
The copies are without entry_pc, but there is on pointer to were to find 
the original info (which may not be present, if that unit did not have 
debug info)



=============================================
On 02/05/2022 09:56, Joost van der Sluis via Lazarusdev wrote:
>
> Hi Martin, and all others,
>
> Freepascal's joost/dwarfproperties branch has support for encoding 
> properties inside the Dwarf debug-info. Properties are basically 
> encoded as references to the underlying fields/methods.
>
> Take this dwarfdump for example:
>
> < 2><0x000000ff>      DW_TAG_member
>                         DW_AT_name                  FProp
>                         DW_AT_data_member_location  len 0x0002: 0x2308:
>                             DW_OP_plus_uconst 8
>                         DW_AT_type <GOFF=0x00000cbb>
> < 2><0x0000010d>      <Unknown TAG value 0x4230>
>                         DW_AT_name                  DoubleProp
>                         <Unknown AT value 0x3230> <0x0000019e>
>                         DW_AT_accessibility DW_ACCESS_public
> < 2><0x0000011e>      <Unknown TAG value 0x4230>
>                         DW_AT_name                  SingleProp
>                         <Unknown AT value 0x3230> <0x000000ff>
>                         <Unknown AT value 0x3231> <0x000000ff>
>                         DW_AT_accessibility DW_ACCESS_public
>
>
> 0x4230 is a property
> 0x3230 is a getter
> 0x3231 is a setter
>
> The SingleProp property references the FProp field.
>
> You can enable this with 'fpc -gw3 -godwarfproperties' using the 
> dwarfproperties branch.
>
> I'm wondering how to handle this in fpDebug. I've did an attempt by 
> creating a symbol that symply forwards everything. But that does not 
> work very well
>
> (https://gitlab.com/jvdsluis/lazarus-propdb/-/commit/d3853c23724ca63e561b82bc357bbf299fc3da1d) 
>
>
> Whay do you think is the best approach? Introduce a new class that 
> represents the property? Or add a lot of trickery to forward what is 
> necessary, but not everything (like the accesibility)
>
> Regards,
>
> Joost.
-------------- next part --------------
program dwarf_prop_test;
{$Mode objfpc}
uses unit1;

type

  { TBar }

  TBar = class(TFoo)
  private
    FBarPropField: byte;
    function GetBarPropGetter: byte;
    function GetBarPropGetter2: byte;
    function GetBarPropGetter3: byte;
  published
    property BarPropField: byte read FBarPropField;
    property BarPropGetter: byte read GetBarPropGetter;
    property BarPropGetter2: byte read GetBarPropGetter2;
    property BarPropGetter3: byte read GetBarPropGetter3;
  end;

  { TSome }

  TSome = class(TBar)
  private
    FSomePropField: byte;
    function GetSomeAAPropGetter3: byte;
    function GetSomePropGetter: byte;
    function GetSomePropGetter2: byte;
  published
    property SomePropField: byte read FSomePropField;
    property SomePropGetter: byte read GetSomePropGetter;
    property SomePropGetter2: byte read GetSomePropGetter2;
    property SomePropGetter3: byte read GetSomeAAPropGetter3;
  end;

{ TSome }

function TSome.GetSomePropGetter: byte;
begin
  Result := Random(222);
end;

function TSome.GetSomePropGetter2: byte;
begin

end;

function TSome.GetSomeAAPropGetter3: byte;
begin

end;


function TBar.GetBarPropGetter: byte;
begin
  Result := Random(222);
end;

function TBar.GetBarPropGetter2: byte;
begin

end;

function TBar.GetBarPropGetter3: byte;
begin

end;


begin
end.

-------------- next part --------------
unit Unit1;
{$mode ObjFPC}{$H+}
interface

type

  { TFoo }

  TFoo = class
  private
    FPropField: byte;
    function GetPropGetter: byte;
    function GetPropGetter2: byte;
    function GetPropGetter3: byte;
  published
    property PropField: byte read FPropField;
    property PropGetter: byte read GetPropGetter;
    property PropGetter2: byte read GetPropGetter2;
    property PropGetter3: byte read GetPropGetter3;
    property PropGetter2a: byte read GetPropGetter2;
  end;


implementation

{ TFoo }

function TFoo.GetPropGetter: byte;
begin
  Result := Random(111);
end;

function TFoo.GetPropGetter2: byte;
begin
  Result := Random(111);

end;

function TFoo.GetPropGetter3: byte;
begin
  Result := Random(111);

end;

end.



More information about the fpc-devel mailing list