[Lazarus] Tracking down an intermittent termination exception
Sven Barth
pascaldragon at googlemail.com
Tue Mar 26 11:46:31 CET 2013
Am 26.03.2013 10:39, schrieb Mark Morgan Lloyd:
> I've got a program here with main and background thread, it doesn't do
> anything fancy like explicitly hooking the event loop. Intermittently
> it displays something like this during termination:
>
> An unhandled exception occurred at $08080639 :
> EInOutError :
> $08080639 CDONECRITICALSECTION, line 503 of ../unix/cthreads.pp
> $08075B84 DONECRITICALSECTION, line 199 of
> /usr/local/src/fpc/fpcbuild-2.6.2/fpcsrc/rtl/inc/thread.inc
> $080D5404 COMMONCLEANUP, line 1751 of
> /usr/local/src/fpc/fpcbuild-2.6.2/fpcsrc/rtl/objpas/classes/classe s.inc
> $080DD8A8 CLASSES_finalize, line 51 of ../unix/classes.pp
> $08072DAF FINALIZEUNITS, line 833 of
> /usr/local/src/fpc/fpcbuild-2.6.2/fpcsrc/rtl/inc/system.inc
> $08072F28 INTERNALEXIT, line 886 of
> /usr/local/src/fpc/fpcbuild-2.6.2/fpcsrc/rtl/inc/system.inc
> $08073038 DO_EXIT, line 937 of
> /usr/local/src/fpc/fpcbuild-2.6.2/fpcsrc/rtl/inc/system.inc
> $0805E44B main, line 69 of BorgUM.lpr
> $B6E57CA6
>
> Looking at classes.inc, I see that the affected line is
>
> DoneCriticalSection(SynchronizeCritSect);
>
> Assuming that this is a problem in my own code, what sort of thing
> should I be looking for?
>
After looking through the following things:
- code of CDoneCriticalSection (in rtl/unix/cthreads.pp)
- man page of pthread_mutex_destroy
- code of fpc_threaderror (in rtl/inc/system.inc)
- code of RunErrorToExcept (in rtl/objpas/sysutils/sysutils.inc)
the most valid assumption is that the critical section is destroyed
while it's in use. As this critical section is only used inside a
Synchronize call from a thread (the mainthread will directly call the
method without any locking) it seems that your background thread is
inside a Synchronize call when you terminate your application.
Solution: Tell the thread to terminate (if you use the thread's
Terminate property you'll need to check this inside your thread's loop)
and then wait for (TThread.WaitFor) it to finish before you continue
with termination. This will also ensure that any cleanup that is done
inside the thread is finished before the RTL is finalized.
Regards,
Sven
More information about the Lazarus
mailing list