[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