Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Exception when a thread terminates

Status
Not open for further replies.

rossmcm

Programmer
Jun 28, 2000
16
0
0
I have a multithreaded app that talks to serial ports. Occasionally I get an exception - I installed MadExcept hoping it would give me more of an idea than D5's reporting: The stack dump I got was:

thread $c58:
0043c63d tad.exe Classes TThread.Synchronize
0043c5ed tad.exe Classes TThread.DoTerminate
0043c4e8 tad.exe Classes ThreadProc
00403da8 tad.exe System ThreadWrapper
0042c173 tad.exe madExcept ThreadExceptFrame

The exception I get is of type 'unknown'.

I never call terminate - the thread.Execute routine looks like:

begin
inc (TotalThreadsRunning)
try
...lots of stuff
except
asm nop end ; // breakpoint on this address to see if we get any exceptions in the thread
end ;
dec (totalThreadsRunning) ;
end ;

The threads are created when needed and freed when finished in the Onterminate handler.

The breakpoint is not struck when these exceptions occur.

The other really curious thing is that the variable TotalThreadsRunning creeps up over time - i.e. when all threads have completed it reads 1 or 2, not zero. This suggests a thread completes without dropping out the bottom. Whether this might be related to the AVs I don't know. The issue with the total threads running counter appears to be related to threads accessing a common global variable - I would have thought that

inc (TotalThreadsRunning)

was indivisible but not so. If I have :

InterlockedIncrement (TotalThreadsRunning2) ;

at the same place in the code, the two variables get out of step eventually.




 
I suppose that TotalThreadsRunning is a global variable.

keep in mind that accessing global variables used in different threads must kept atomic. InterlockedIncrement is ok to use.

I use the following framework for all my threads and I've never ran into problems

Code:
procedure TMyThread.Execute(Sender: TService);

begin
 //service main body - init phase
 try
  try 
   EnterCriticalSection(SyncHandle)
   Inc(ThreadCount); 
   // do other things in shared memory
  finally
   LeaveCriticalSection(SyncHandle);
  end;
// use the same technique in the OnTerminate event 
 except
  on E : Exception do
   begin
    DebugOutput(Format('thread -> critical error : "%'))
   end;
 end;
end;



--------------------------------------
What You See Is What You Get
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top