[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 14:23:41 CEST 2013


Thanks Ludo, but I know the value in (%eax) in this case is nil (see the
cpu register dump in my email) because the address of the string length (in
edx) is 0xfffffff8 (which is "8 less than nil") per the instruction just
before the one that fails with SEGV. The SEGV itself is caused by an
attempt to read the address in edx, i.e. 0xfffffff8 at the instruction cmpl
$0,(%edx).

The corruption is not occurring when the return value of foo is used, it's
occurring when the Result variable in foo is first assigned (a valid
string, '') when Result first appears in scope of the body of the function
foo.

Thanks for your feedback. Cheers, Bruce.


On Thu, May 9, 2013 at 4:21 PM, Ludo Brands <ludo.brands at free.fr> wrote:

> On 05/09/2013 05:19 AM, Bruce Tulloch wrote:
> >
> > This tells me that the test at the top of fpc_AnsiStr_Decr_Ref:
> >
> >         cmpl $0,(%eax)
> >         jne .Ldecr_ref_continue
> >         ret
> > .Ldecr_ref_continue:
> >
> > passed (i.e. (%eax) was NOT nil) but sometime during the execution of
> > the following code:
> >
> > // Temps allocated between ebp-24 and ebp+0
> >         subl    $4,%esp
> > // Var S located in register
> > // Var l located in register
> >         movl    %eax,(%esp)
> > // [101] l:=@PAnsiRec <mailto:=@PAnsiRec>(S-FirstOff)^.Ref;
> >         movl    (%eax),%edx
> >         subl    $8,%edx
> > // [102] If l^<0 then exit;
> >         cmpl    $0,(%edx)
> >
> > the variable (%eax) MUST have been changed (to nil) BY ANOTHER THREAD.
> >
> > Is there any other plausible explanation I may have missed?
> >
>
> SIGSEGV is caused by an access to any memory outside the process address
> space. Not only nil. So the first test only checks if the address is not
> nil but will let other, even invalid, addresses pass on.
>
>
> > If there is no other explanation, then it means I need to find out how
> > the string variable referred to by (%eax) could have been been accessed
> > (or even known to exist) by any other thread in the same address space.
> >
> > If that variable is local to a function (i.e. foo's Result with SEGV
> > upon its assignment immediately it first comes into scope, per my
> > earlier email) then absent a bug in FPC's handling string references and
> > allocation, it seems impossible that it could be known or referenced by
> > any other other thread.
> >
> > I'm reasonably confident there's no other way it could be overwritten by
> > another thread (i.e. I don't think there are any range or buffer pointer
> > errors anywhere else) so logic tells me I must have the wrong thesis or
> > there's a string handling error in FPC.
> >
> > Any clues or insight, gratefully received :-)
> >
>
> Result in foo is initialized with the address of the left side variable
> in the call to foo. If you have
>   s:=foo;
> result will point to s. If you just call
>   foo;
> and drop the result, the compiler will create and use a hidden temp
> string variable. Strings are managed types and initialized to nil.
>
> So you are looking at the wrong location for your bug. You should look
> at what has corrupted the string variable that receives the result of foo.
>
> Ludo
> _______________________________________________
> 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/a2da7df1/attachment.html>


More information about the fpc-pascal mailing list