[fpc-devel] Insufficient Dwarf info for Interfaces

Martin Frb lazarus at mfriebe.de
Fri Sep 16 00:09:04 CEST 2022

On 15/09/2022 21:35, Sven Barth via fpc-devel wrote:
> Am 15.09.2022 um 14:32 schrieb Martin Frb via fpc-devel:
>> https://gitlab.com/freepascal.org/fpc/source/-/issues/39904
>> On top of adding the functions in the interface to the dwarf info, it 
>> would be great if the compiler could also add some sort of link to 
>> the underlaying TObject.
>> So the debugger could (if available) show the user the 
>> object/instance that implements the interface.
>> I am not sure how that would best be done (i.e. maybe add some 
>> internal field, maybe there is some dwarf tag that can be used, maybe 
>> a dwarf extension....)
>> From what I  understand, this would require the offset between the 
>> interface table and the class (i.e. the value that is subtracted from 
>> "self" in the interface's method).
>> If for a debug build the compiler could write that value in front of 
>> the interface, then it could point the debugger to it....
> You are aware that an interface can be implemented by multiple 
> different class types and that the offsets for each class that 
> implements a specific interface will be different depending on the 
> amount of interfaces a class implements? So if you have a given 
> interface neither you nor the compiler will know what is on the other 
> side.

And I am also aware that for each class that implements the interface, 
their is a separate set of jump pads (with code adjusting "self" by that 
offset), and there is a "interface vmt" for those jump pads.

If TFoo implements ISome, then A:ISome = $100010
If TBAr implements ISome, then A:ISome = $102210

So there are 2 options
1) the compiler writes the "offset" at $100008 and $102208 (4 or 8 bytes 
before). (only if debug info generation is on)
The the debugger needs to figure out this is implemented by a class (and 
not external)

2) The compiler writes separate dwarf for the 2 version of the 
"interface vmt".
And It says "this is at address xxxx"
THen the debugger does a reverse lookup by address => and finds the 
dwarf info for the "interface vmt"
The problem is to find what dwarf info to use. It must include the 
address, and then the offset (or an dwarf expression to calculate the 
object instance).
This dwarf info for the interface can also link to the type of the 
instance (the class that implements the interface)

The compiler already writes stuff to dwarf like
   with name   $VMTDEF$TBARU2
   and a size
   but no other info.

Unfortunately this is a type declaration, so it does not have an 
address... (which is really required)

This will likely need a custom dwarf entry. Or tweaking an existing, 
such as including an DW_AT_Location
OR a DW_TAG_VARIABLE to hold the address for this type

All the info is already there, except really not accessible.

If the debugger has an interface, and it says address=$1002233
=> the debugger can look up the first method of the interface
=> check the code is in one of the compilation units (code generated 
from pascal source)
=> disassemble the code to get the offset
=> calculate the address of the object instance
=> use RTTI to get the classname.
=> find the dwarf for that class, typecast, and voila

More information about the fpc-devel mailing list