[fpc-devel]implicit calls to _addref / _release fail

Johannes Berg johannes at sipsolutions.de
Thu Nov 27 23:13:44 CET 2003


Hi,

Rather than dumping all this information into a bug report I decided to
write an email.

Here's a test program (attached) and a discussion of what goes wrong.
Thanks again to Marco for explaining this to me and walking me through.

For the line
  __globi := TTest.Create;
a few things are generated:
 a) a call to TTest.Create
 b) a call to fpc_intf_assign, which in turn calls TTest._AddRef

the call to Create is fine, nothing wrong with it. However, the call to
_AddRef goes wrong.

Now, heres what this actually looks like:

This is the call to Create and to intf_assign is fine:
        call    SYSTEM_TOBJECT_$__CREATE
        testl   %eax,%eax
        je      .L16
        addl    $44,%eax
.L16:
        pushl   %eax
        pushl   $U_P$TESTII___GLOBI
        call    fpc_intf_assign

fpc_intf_assign calls AddRef from the VMT, which points to this code:

WRPR_P$TESTII_TTEST_$_ITESTINT_$_2_$_SYSTEM_TINTERFACEDOBJECT_$___ADDREF:
        subl    $44,(%esp)
        jmp     SYSTEM_TINTERFACEDOBJECT_$___ADDREF

Marco explained to me that this looks like tailcall optimization,
however for one this doesn't even make sense here (because
fpc_intf_assign has to do something else [check the destination and
_release on it] after _addref); however this is the reason why the
program bombs out.

The call %eax in fpc_intf_assign pushes the correct return address
within fpc_intf_assign onto the stack. Now, above code decrements it by
44 (0x2C). The new return address is now the following instruction from 
fpc_intf_incr_ref:
                mov     (%eax), %eax

Which segfaults immediately because %eax contains the return value of
_addref (stdcall calling convention) which is 1 in this case.

I don't really know where the problem is (ie, why the compiler generates
this code), however this keeps reference counted interfaces from working
at all.

johannes
-- 
http://www.sipsolutions.de/
GnuPG key: http://www.sipsolutions.de/keys/JohannesBerg.asc
  Key-ID: 9AB78CA5 Johannes Berg <johannes at sipsolutions.de>
  Fingerprint = AD02 0176 4E29 C137 1DF6 08D2 FC44 CF86 9AB7 8CA5
-------------- next part --------------
program testii;
{$MODE OBJFPC}
uses
  baseunix;
type
  ITestInt = interface(IInterface)
  end;
  TTest = class(TInterfacedObject, ITestInt)
   a,b,c,d,e,f,g,h:integer;
  end;
                                                                                
var
  __globi: ITestInt;

begin
  fpsleep(15);
  __globi := TTest.Create;
end.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 194 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20031127/40645bb6/attachment.sig>


More information about the fpc-devel mailing list