[fpc-devel] threads vs widestringmanager / crash

Ondrej Pokorny lazarus at kluug.net
Sat Dec 17 17:11:50 CET 2022


I have the same problem. It is very annoying because programs crash 
quite often when run in a debugger (on Windows).

I solved it with the attached patch - I added these lines to procedure 
OpenStdIO(var f:text;mode:longint;hdl:thandle);

   {$if defined(FPC_HAS_CPSTRING) and defined(FPC_HAS_FEATURE_WIDESTRINGS)}
     while not Assigned(WideStringManager.GetStandardCodePageProc) do
       ;
   {$endif}

The problem is that
procedure InitThread(stklen:SizeUInt);
is called before the WideStringManager properties are set in system 
initialization when debugger is present.

How to solve it properly? Can the InitThread() procedure somehow wait 
until the system initialization is done? E.g. with a global variable set 
with InterLockedIncrement()? Would such a patch be accepted in FPC?

I'd like to solve the problem on FPC level to avoid my own patches.

Thanks
Ondrej


Am 07.07.2018 um 14:40 schrieb Martin:
> There actually isnt a thread started.
>
> But during initialization "TThread.Queue" is called (because the code 
> in question can be called in threads aswell, and must ensure work is 
> done in the main thread)
>
> "TThread.Queue" creates a new external thread. This fails during unit 
> initialization for the reason below.
>
> This leads me to the following questionQ
>
> 1) out of interest.
> If "TThread.Queue" is called in the main thread, then it does not 
> queue anyway, but rather run immediately.
> In this case, why not avoid creating a thread, and check 
> "CurrentThreadVar = nil" ?
>
> 2) how to solve my problem. (including other OS, for which I do not 
> know if the issue exists)
> - Is there a way to test, if current code is in the main thread? (and 
> doing so, without creating a TThread instance)?
>
> - If not, then for windows (and fpc 3.0.4) the following *should* do 
> (but is really rather a hack)
>   {$IFDEF MsWindows}  if WideStringManager.GetStandardCodePageProc = 
> nil then
>
> Any better ideas?
>
>
>
> On 07/07/2018 14:00, Martin wrote:
>> fpc 3.0.4
>> Win 10 / 32bit
>>
>> Lazarus trunk, but that may not be relevant.
>> This is the first time I am seeing this, and I am therefore not sure 
>> I will be able to reproduce, since it seems a race condition.
>>
>> This appears to happen during unit initialization.
>>
>> Something must have started a thread, before widestring manager got 
>> initialized.
>> In other word, some unit (used in such order that it's initialization 
>> runs before unit system initialization) has started a thread.
>>
>> This thread crashes, if it is fast enough, because in the threads 
>> init it will access widestringmanager.
>>
>> Is this a bug in fpc?
>> Or is this wrong of the calling code (eg starting threads during unit 
>> initialization).
>>
>> In the latter case, is it documented?
>>
>> The trace from the thread:
>> #0 ?? at :0
>> #1 OPENSTDIO({}, 55217, 168) at ..\inc\text.inc:2670
>> #2 SYSINITSTDIO at ..\win\syswin.inc:520
>> #3 INITTHREAD(16777216) at ..\inc\thread.inc:59
>> #4 EXEC_TLS_CALLBACK(0x400000, 2, 0x0) at ..\win\systlsdir.inc:90
>> #5 ntdll!WinSqmSetDWORD64 at :0
>> #6 ?? at :0
>> #7 ntdll!RtlDeactivateActivationContextUnsafeFast at :0
>> #8 ntdll!RtlCaptureStackContext at :0
>> #9 ntdll!LdrShutdownThread at :0
>> #10 ntdll!LdrInitializeThunk at :0
>> #11 ntdll!LdrInitializeThunk at :0
>> #12 ntdll!LdrInitializeThunk at :0
>> #13 ?? at :0
>>
>> The main thread sit right before widestring initialization.
>> #0 INITUNICODESTRINGMANAGER at ..\inc\ustrings.inc:2311
>> #1 SYSTEM_$$_init$ at :674
>> #2 fpc_initializeunits at ..\inc\system.inc:886
>> #3 main at lazarus.pp:87
>>
>> _______________________________________________
>> fpc-devel maillist  -  fpc-devel at lists.freepascal.org
>> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
>
> _______________________________________________
> fpc-devel maillist  -  fpc-devel at lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
-------------- next part --------------
diff --git "a/C:\\Users\\ONDREJ~1\\AppData\\Local\\Temp\\TortoiseGit\\text-1b4616c.000.inc" "b/P:\\software\\FPC\\trunk_src\\rtl\\inc\\text.inc"
index c2ef94fbaa..ddee0867f7 100644
--- "a/C:\\Users\\ONDREJ~1\\AppData\\Local\\Temp\\TortoiseGit\\text-1b4616c.000.inc"
+++ "b/P:\\software\\FPC\\trunk_src\\rtl\\inc\\text.inc"
@@ -2753,6 +2753,10 @@ procedure OpenStdIO(var f:text;mode:longint;hdl:thandle);
   TextRec(f).Handle:=hdl;
   TextRec(f).Mode:=mode;
   TextRec(f).Closefunc:=@FileCloseFunc;
+  {$if defined(FPC_HAS_CPSTRING) and defined(FPC_HAS_FEATURE_WIDESTRINGS)}
+    while not Assigned(WideStringManager.GetStandardCodePageProc) do
+      ;
+  {$endif}
   case mode of
     fmInput :
       begin


More information about the fpc-devel mailing list