Sign in Join

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

Mailing lists / fpc-devel / 2003-11

implicit calls to _addref / _release fail

2 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

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

Johannes Berg

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 Fingerprint = AD02 0176 4E29 C137 1DF6 08D2 FC44 CF86 9AB7 8CA5

Reply by email

Peter Vreman
to Johannes Berg
Show quoted text 6 lines
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.

Fixed. Problem was the wrong calculation of the offset of self seen from the caller side

Reply by email