Discussion:
threads vs widestringmanager / crash
(too old to reply)
Martin
2018-07-07 12:00:11 UTC
Permalink
Raw Message
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-***@lists.freepascal.org
http://list
Martin
2018-07-07 12:40:42 UTC
Permalink
Raw Message
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?
Post by Martin
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?
#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
_______________________________________________
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
_______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailm
Martin
2018-07-07 13:04:05 UTC
Permalink
Raw Message
Ok, I guess the "TThread.Queue"  is wrong.
Because that may create an instance, but there would not actually be a
2nd thread as observed. (Question 1 is still interesting)

Yet there is no other TThread.Create call made.

So (guessing) the original issue may be due to the debugger. The
debugger interrupts the target early on. And that does create a thread
in the target.
If such an external thread happens, would fcp execute the code in question?

Could/Should there be a nil check at the location of the crash?
Post by Martin
"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" ?
Post by Martin
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?
#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
_______________________________________________
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
_______________________________________________
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
_______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mai

Loading...