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)

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);
    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.

fpc-devel maillist  -  fpc-devel@lists.freepascal.org

Reply via email to