On Wed, 8 May 2013, Bruce Tulloch wrote:

 After a random but very long period of time (i.e. very many successful calls) 
I get a SEGV in the built-in function fpc_AnsiStr_Decr_Ref.

GDB reports the argument to fpc_AnsiStr_Decr_Ref (the string who's reference is 
to be decremented) is nil (i.e. 0x0).

Prima facie, that's the reason for the SEGV, but how is it possible that the 
compiler would pass a nil pointer to this function the first place?

To put this into context, I'm running FPC 2.6.2 on a 32 bit Linux system 
executing in a multi-threaded application (which uses python threads and fpc 
threads). I have not found obvious
evidence of memory corruption from other execution contexts or shared memory 
handling problems.

The SEGV occurs when called from a function, let's call it foo, that looks like 
this:

function foo : AnsiString;
begin
  Result := '';
 <other stuff>
end;

The AnsiString pointer that fpc_AnsiStr_Decr_Ref throws a SEGV is Result, at 
the first line of the function foo.

It appears the compiler is passing Result to fpc_AnsiStr_Decr_Ref even though 
Result (at this point in the function) must be nil (having only just come into 
scope).

This is not correct. Result is NOT guaranteed to be nil.

About a year ago,  I was as surprised as you are to discover this, but it is so.
It is even so in Delphi.

How is is possible that fpc_AnsiStr_Decr_Ref is being called at all?

Roughly:

What happens is that the caller gives the address of the location where the 
result must go.
The function receives this address, and then treats it as a normal variable, meaning that as soon as it is used, fpc_AnsiStr_Decr_Ref and friends come into play.

The exact behaviour also depends on the compiler version.

One of the compiler maintainers can describe this in more detail.

Michael.
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to