[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