Jump to content
Sonjli

Task dies unexpectedly

Recommended Posts

Hello,

I have a task which dies unexpectedly and I don't know how to check this situation.

I know for sure it is something related with my software. I added all the "try\except" needed to catch the exception but the task dies the same.

The task (I will call it "Child") is created by a MainTask, but when the child dies, the father continues without problems.

The Main Task creates a lot of this Child. Every child is good isolated. There are not concurrent resources used between them.

The child task contains an infinite loop testing the task.terminated.

The child task is added to a TaskGroup and I tested that when it "dies bad" also disappear from TaskGroup.

The "OnTerminated" on child does not trigger in this scenario. The child thread never call the OnTerminated, neither in "good termination" case. I don't know why.

I don't know how to catch the "FatalException" of the child.

How can I test this?

I don't know how many other infos you need.

 

Thanks,

Eddy

Share this post


Link to post

If you run your program in debugger, it should pop up when the exception occurs - unless you have that exception type listed on the 'ignored exception' list.

 

Alternatively, open OtlTaskControl unit and search for TOmniTask.InternalExecute. Inside you'll find:

        try
          if otSharedInfo_ref.ProcessorGroup >= 0 then
            otExecutor_ref.SetProcessorGroup(otSharedInfo_ref.ProcessorGroup);
          if otSharedInfo_ref.NUMANode >= 0 then
            otExecutor_ref.SetNUMANode(otSharedInfo_ref.NUMANode);
          otExecutor_ref.Asy_Execute(Self);
        except
          on E: Exception do begin
            taskException := Exception(AcquireExceptionObject);
            FilterException(taskException);
            if assigned(taskException) then
              SetException(taskException);
          end;
        end;

This is the main exception handler for a task. You can log information inside the exception handler or put a breakpoint there.

  • Thanks 1

Share this post


Link to post
6 minutes ago, Primož Gabrijelčič said:

If you run your program in debugger, it should pop up when the exception occurs - unless you have that exception type listed on the 'ignored exception' list.

 

Alternatively, open OtlTaskControl unit and search for TOmniTask.InternalExecute. Inside you'll find:


        try
          if otSharedInfo_ref.ProcessorGroup >= 0 then
            otExecutor_ref.SetProcessorGroup(otSharedInfo_ref.ProcessorGroup);
          if otSharedInfo_ref.NUMANode >= 0 then
            otExecutor_ref.SetNUMANode(otSharedInfo_ref.NUMANode);
          otExecutor_ref.Asy_Execute(Self);
        except
          on E: Exception do begin
            taskException := Exception(AcquireExceptionObject);
            FilterException(taskException);
            if assigned(taskException) then
              SetException(taskException);
          end;
        end;

This is the main exception handler for a task. You can log information inside the exception handler or put a breakpoint there.

Thank you very much for the fast response.

Naturally, this bug don't comes with debugging but in real production from customer...

I'll try the logging solution. Thanks again.

 

ps: any idea for the OnTerminated event in the child task?

Share this post


Link to post
4 minutes ago, Sonjli said:

any idea for the OnTerminated event in the child task?

Missed that one, sorry.

 

If a OnTerminated is not called (but is called when the task does not die), then the task is probably killed with TerminateThread somewhere.

Share this post


Link to post

Don't sorry, it's me the one bothering...

The OnTerminated is not called even when everything goes right.

The strange thing is that the messaging system (task.comm and OnMessage) is perfectly ok.

Share this post


Link to post

To kill the "childs" I do this:

 

   FCancellationToken.Signal;
   FPlugsGroup.WaitForAll;

 

FPlugsGroup is the group for the childs

Share this post


Link to post

If the OnTerminated is not called, then the task owner (MainTask) is not processing messages. If MainTask is an OTL task, then you can just call it's function MsgWait when you create it.

MainTask := CreateTask(TOmniWorkerDescendant.Create()).MsgWait;

 

  • Thanks 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×