[fpc-pascal] FPC 2.6.2 throws SEGV in fpc_AnsiStr_Decr_Ref(). How is this possible?

Bruce Tulloch pascal at causal.com
Thu May 9 01:35:03 CEST 2013


Michael, thanks for your feedback.

One thing that confuses me in light of Jonas' reply, if what you say is
correct (that local variables that have just come into scope are not
guaranteed to be nil) then assignment of Result := ''; at the first line of
foo may arbitrarily SEGV because fpc_AnsiStr_Decr_Ref will interpret the
(possibly) non-nil value (of Result) as an AnsiString which (being a random
uninitialized value) will likely be incorrect and blow up.

Surely the semantics of string handling relies on FPC guaranteeing
automatic variables are always preassigned nil when they come into scope?

Put another way, how does fpc_AnsiStr_Decr_Ref and friends, which receive
the address of the caller's Result variable via their var parameter know
that the value of this parameter (which may not be initialized if what you
say is correct) is or is not a valid string?

Bruce.

On Wed, May 8, 2013 at 5:18 PM, Michael Van Canneyt
<michael at freepascal.org>wrote:

>
>
> 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 at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20130509/0de5f4a0/attachment.html>


More information about the fpc-pascal mailing list