I have a project for a windows service which starts a thread to do some job, this part has been working for a long time, so not part of the problem. What I am trying to do is when this job starts and ends, it should start another thread (EventMessenger that inherited TThread) to send emails with a notification about the job has started and ended. I know you can not have nested threads, but i think it should ok to start one thread from another, then it will just belong to the main process. I create the thread in suspended mode, but i am uncertain whether it is ok to call assign for objects on the thread object while it is suspended.
EventMessenger := TEventMessenger.Create(true); // true = start suspended
EventMessenger.StatusCode := AStatusCode;
EventMessenger.Receiver.Assign(Receiver);
EventMessenger.MessageOptions.Assign(MessageOptions);
EventMessenger.MessageDetails := AMessage;
EventMessenger.FreeOnTerminate := true;
EventMessenger.Resume;
The Execute for TEventMessenger sends a mail using Indy TIdSmtp, here is a part of the code
try
self.FMessage.From.Address := ASender;
self.FMessage.Recipients.EMailAddresses := AReceiver;
self.FMessage.Subject := ASubject;
self.FMessage.Body.Text := AMessage;
try
self.FSMTP.Connect;
self.FSMTP.Send(self.FMessage);
except
on E:EIdException do
begin
CurrentEurekaLogOptions.ExceptionDialogOptions := []; // Don't show dialog box
StandardEurekaNotify(E, ExceptAddr()); // Save exception to file
end;
end;
finally
if self.FSMTP.Connected then
self.FSMTP.Disconnect;
end;
The first time i start the thread EventMessenger it works fine and sends an email about the job has started. However when it starts the EventMessenger again to send a mail about the job has stopped, i got a stack overflow in ntdll. I wonder if the assign in suspended mode can mess up the stack or whether there is some problem in indy; read that it could case problem if exceptions where not masked when mixing managed/unmanaged code, not sure whether this has anything to do with it. Note: I'm not using the default Indy in Delphi 2009, as it has several bugs, I'm running with Indy10 code downloaded from their repository in January.
:779e010f ntdll.KiUserExceptionDispatcher + 0xf
:77a2878b ; ntdll.dll
:779e010f ntdll.KiUserExceptionDispatcher + 0xf
:77a2878b ; ntdll.dll
:779e010f ntdll.KiUserExceptionDispatcher + 0xf
:77a2878b ; ntdll.dll
Any one got a idea what the actually problem is that causes the stack overflow or how i can catch the exception? I have wrapped the indy send in try/except, but i guess that only works for main process not threads, so I also added a try/except around the code in the EventMesssenger.Execute which calls HandleException that I have implemented like the following code, however it service crashes with AV without entering the ExceptionHandler.
procedure TEventMessenger.DoHandleException;
begin
if FException is Exception then
begin
CurrentEurekaLogOptions.ExceptionDialogOptions := []; // Don't show dialog box
StandardEurekaNotify(FException, ExceptAddr()); // Save exception to file
end;
end;
procedure TEventMessenger.HandleException;
begin
FException := Exception(ExceptObject);
try
if not (FException is EAbort) then
Synchronize(DoHandleException);
finally
FException := nil;
end;
end;