[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
compiling.
When I cause an exception inside the sub-thread, then in the main
thread, I get
procedure ExecuteThreadQueueEntry(aEntry: TThread.PThreadQueueEntry);
begin
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