[fpc-devel] Suspicion about TThread.Synchronize

Martin fpc at mfriebe.de
Mon Feb 5 00:43:43 CET 2018

On 04/02/2018 20:33, Martin wrote:
> On 04/02/2018 20:23, Sven Barth via fpc-devel wrote:
>> Would you please test whether my change in r38115 (applied to 3.0.2)
>> makes any difference? Calling RemoveQueuedEvents() with a thread, but no
>> method (which happens during a thread's destruction) was up to then a
>> way to corrupt the queue. (Well, it could still corrupt the queue if a
>> thread instance is freed while its blocked inside a Synchronize call,
>> but that is asking for a whole different sort of trouble anyway)
> Thanks.
> I will apply the patch. And wait if the error still happens.

Well, I am back faster than I thought, applied the patch, rebuild the 
IDE, and it still happened.
Well this time I was able to get it while the IDE was already running. 
But exact same stack.

I used a breakpoint on ThreadQueueAppend to see what threads are 
involved ( I figure, this must be called, for the error to happen)

During startup, the only threads I could detect, are 
online-package-manager. This is new, and I havent had it installed for 
long, so quite possible (given that I havent seen the crash until recently).

The other location, was in a thread running the compiler, when the IDE 
compiles a project. This code been there for longer.

In the online package manager, as far as I was able to get by now, it is 
possible that an exception occurred somewhere.
I can't get it to happen in the debugger, probably because the debugger 
changes timings.

I have been able to force an error in the opm, and get a different error 
in checkSyncronize.  (30% chance in the debugger)

Maybe it is the same, just a diff timing....  If the debugger had not 
interfered, collecting info, then maybe the destroy would have been a 
tick later, in PopThreadQueueHead
Dont know for sure.....

Also, even if the below is related, this may not explain the error while 

When I cause an exception inside the sub-thread, then in the main 
thread, I get
   procedure ExecuteThreadQueueEntry(aEntry: TThread.PThreadQueueEntry);
     if Assigned(aEntry^.Method) then
       aEntry^.Method()    /// aentry points to F0F0F0F0

But the important thing here is, the sub thread that send the event is 
in REMOVE_FREED_FIXED_CHUNKS called from its destroy.

So yes it seem the thread gets destroyed, while the event is still in 
the queue.

To go more into detail. Though I havent yet fully figured it.....

There are actually 4 threads (thread id)
- main (1)
- threadtimer (this will create the 2 other threads) (2)
- threadtimer for timeout (3)
- opm thread (4)

the below order of events is established by breakpoints that where hit 
during debugging

timout -> ThreadQueueAppend
opm -> ThreadQueueAppend
main -> checksynchronize
   ...     PopThreadQueueHead  (before the "while" in CheckSynchronize 
// new call to CheckSynchronize)
   ...    an exception occured inside the event (this should be the 
event of the timeout timer)
   ...     PopThreadQueueHead   (inside/end of "while" in 
CheckSynchronize // still SAME call to CheckSynchronize)
opm -> leaves it DoExecute loop // but if I am right, its event has not 
yet been executed...

Now it is getting weird (probably because opm is already freeing mem
main has 3 further calls to  PopThreadQueueHead -> ALL (inside/end of 
"while" in CheckSynchronize // still SAME call to CheckSynchronize)
The while loop should have exited, there are no matching ThreadQueueAppend
(I do not have a stacktrace for opm2 at this time....)

After that the crash happens.  (opm2 is inside its destroy)

I have no idea why or how the opm thread leaves it DoExecute, while it 
should still wait for its synchronize to finish.

The timout thread would probably have finished, since I did not find a 
try except around the synchronize in it.

More information about the fpc-devel mailing list