[fpc-devel] double free of internal temp string with fpc 3.2.0

baldzhang baldzhang at 163.com
Fri Jan 8 23:13:44 CET 2021


I have the same problem after upgrade to 3.2.0, 3.0.4 is all good.

In my program, when free a TStringList that used in a thread, exception occurs in 80%~90% time.
I try to finger out what happening and got fpc_ansistr_decr_ref calling FreeMem then got wrong memory.
The program was x86-64 on Windows 10.

I haven't dig so deep like Martin has done, but I think it's the same problem.


At 2021-01-09 00:11:19, "Martin Frb via fpc-devel" <fpc-devel at lists.freepascal.org> wrote:
>I only tested with 3.2.0 so far. Maybe someone recalls if this is fixed 
>or not.
>
>Also because it seems to happen only in very rare conditions, it may be 
>that trunk does not cause it in this place even if the bug is not yet 
>fixed. (as other code changes could simply change the context enough to 
>mitigate it)
>
>
>Using fpc 3.2.0
>compiling lazarus  SVN 64346 at trunk with -gw -gl -gt -Criot -Sa -O-1 -gh -gv
>(this also happened at -O3 / but I could not trace it as valgrinds 
>reported stack was unreadable  / The attached valgrind is with -O-1)
>
>unit MaskEdit
>procedure TCustomMaskEdit.SetMask(Value : String);
>
> From the generated ASM
>
># Temps allocated between rbp-696 and rbp-296
>
># [575] for I := 1 To Utf8Length(S) do
>     leaq    -400(%rbp),%rdi
>     call    fpc_ansistr_decr_ref at PLT
>     leaq    -408(%rbp),%rdi
>     call    fpc_ansistr_decr_ref at PLT
>     leaq    -272(%rbp),%rsi
>     xorl    %edx,%edx
>     leaq    -408(%rbp),%rdi
>     call    fpc_shortstr_to_ansistr at PLT
>     movq    -408(%rbp),%rsi   ////// 
><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>     movq    %rsi,-400(%rbp)
>     testq    %rsi,%rsi
>     je    .Lj156
>     movq    -8(%rsi),%rsi
>.Lj156:
>     movq    -400(%rbp),%rdi
>     testq    %rdi,%rdi
>     jne    .Lj157
>     movq    FPC_EMPTYCHAR at GOTPCREL(%rip),%rdi
>.Lj157:
>     call    LAZUTF8_$$_UTF8LENGTH$PCHAR$INT64$$INT64 at PLT
>
>On the marked line, the string (ref) in temp(-408) is copied to temp(-400).
>But the refcount is NOT increased
>
>*****
>Temp(-408) is later passed as "var param Result" to
>
># [741] FTextOnEnter := inherited RealGetText;
>     movq    -16(%rbp),%rdi
>     leaq    -408(%rbp),%rsi
>     call STDCTRLS$_$TCUSTOMEDIT_$__$$_REALGETTEXT$$TTRANSLATESTRING at PLT
>
>This will assign an empty string (in this case), and free the memory 
>(apparently the refcount happens to be 1 at that time)
>
>*****
>in the autogenerated code for the procedures "end" statement:
>
># [743] end;
>     leaq    -408(%rbp),%rdi
>     call    fpc_ansistr_decr_ref at PLT
>     leaq    -400(%rbp),%rdi
>     call    fpc_ansistr_decr_ref at PLT
>
>Temp-408 is already free (or may have a new value that gets correctly freed)
>
>Temp-400 still points to the already freed string => double free.
>
>
>
>
>
>


More information about the fpc-devel mailing list