This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

E_stackOverflow on Task_delete()

Other Parts Discussed in Thread: TM4C1294NCPDT, SYSBIOS

Hi,

I am running code under TiRTOS on a TM4C1294NCPDT.

I want to delete threads that become TERMINATED, so in the .cfg file I set Task.deleteTerminatedTasks = true; and Task.allBlockedFunc = Idle.run;

This does indeed delete two tasks that terminate, but I get ti.sysbios.knl.Task: line 373: E_stackOverflow: Task 0x20002bd0 stack overflow. 2bd0 is the handle of the second deleted task.

I have also tried using Delete_task() with the same effect, can anyone tell me what's going on please?

Thanks

Richard

  • Hi,
    I think this has to be an error in the stack checking as it seems to be checking the stack of a deleted task.
    If I set Task.checkStackFlag = false the program works just fine.
    Can anyone confirm this is an error? I'm using bios 6_45_02_31 and ndk 2_25_00_09
    Thanks
    Richard
  • Hi,
    I have to add that after a few delete/create tasks I run out of heap memory, so the delete task is not managing memory correctly - anyone any idea how to fix it?
    Regards
    Richard
  • Richard Bland said:
    I think this has to be an error in the stack checking as it seems to be checking the stack of a deleted task

    It's normal for an "exited" Task to get its stack checked one last time (but only one time, not repeatedly).  When a Task falls out of its function, it falls into Task_exit().  Task_exit() blocks the Task, marks it as terminated, and places the Task on a "terminatedQ" and then calls the scheduler, during which time Task_checkStacks() is called on the old (exiting) Task and the next Task.  The Task will eventually get deleted by an Idle function, so that won't happen until the system has been idle.

    Richard Bland said:
    If I set Task.checkStackFlag = false the program works just fine.

    There is still probably an overflowed stack that just happens to not crash the system, and now you're just not hearing about it.

    Can you increase the stack size of all Tasks?  If so, please try that and then check to see how much of the stack the Tasks are using.  You can see that by looking at the Task tab of the ROV tool in CCS.

    Regards,

    - Rob

  • Richard Bland said:
    I have to add that after a few delete/create tasks I run out of heap memory, so the delete task is not managing memory correctly

    While one can never state that a body of code is bug-free, the Task_create()/delete() code has been around for a long time and been heavily used by many customers.  It is unlikely that there is a memory leak there.

    It is much more likely that your Task has a memory leak.  Could you check the heap usage with the ROV tool?  Perhaps it would help to check heap usage at the very start of your Task and then check it again when the Task exits?

    Can you include your app code (CCS project?).

    Regards,

    - Rob

  • Hi Rob,
    Thanks for the info and your time.
    I agree, it has to be a mistake in my project.
    I started from the TCPEcho example project which, with minimal modification, runs on my hardware. I can see the TCPWorker thread is created and automatically deleted when it exits.
    My own code which is almost identical does not automatically delete this thread when it exits. I have checked that the .cfgs are the same.
    What I notice is that the idle task in my code is blocked, whereas it's running in the echo example. Could you tell me how to find out what is blocking my idle loop please.
    Thank you
    Richard
  • I should add that when I pause the debugger all my tasks are blocked. ie there isn't one task hogging the cpu.
    Also the stack size on the tasks which exit are 2048 and their peaks are <1500.
    Richard
  • In my code the Idle task changes from Ready to Blocked immediately after the accept() has created a new server socket.
    This does not happen in the echo example.
  • Richard Bland said:
    In my code the Idle task changes from Ready to Blocked immediately after the accept() has created a new server socket.
    This does not happen in the echo example.

    Well that's not good.  The Idle Task should *always* be Ready and never Blocked.

    Have you added any functions to the Idle thread?

    Regards,

    - Rob

  • No, I didn't even know I had an idle thread running until a couple of days ago!
    In ROV it says blockedOn Internal Error (last column in Detailed tab). Does this mean anything to you?

    Regards
    Richard
  • Can you click the BIOS module in ROV and then select the "Scan for errors..." tab and see what it says?

    Regards,

    - Rob

  • Hi Rob,

    I have discovered that if I don't run this code which starts a clock thread, the idle doesn't block!
    void initPollClock(void)
    {
    Clock_Params clockParams;
    Clock_Handle myClock;
    Error_Block eb;

    Error_init(&eb);
    Clock_Params_init(&clockParams);
    clockParams.period = 10; //10mS clock thread
    clockParams.startFlag = TRUE;
    //clockParams.arg = (UArg)0x5555;
    myClock = Clock_create((ti_sysbios_knl_Clock_FuncPtr)pollTasks, 5, &clockParams, &eb);
    if (myClock == NULL) {
    System_abort("Clock create failed");
    System_flush();
    }
    }

    Does this give us a clue?

    Regards
    Richard
  • Hi Rob,
    I have now systematically removed each of the functions in the clock thread "pollTasks".
    One of the calls in this thread ran a function which has Task_sleep(110) to create a 110mS delay.
    If I don't call this, all is OK. Is it not allowed to use Task_sleep() in a clock thread?

    Thanks for your help
    Richard
  • It seems that must be the case as I have implemented the delay by counting each time the clock thread runs and all is working.
    I've got alot to learn - sorry!
    Best regards
    Richard
  • Richard Bland said:
    If I don't call this, all is OK. Is it not allowed to use Task_sleep() in a clock thread?

    That's right, you have found the problem.  A Clock instance's function runs in SWI context, which cannot call any blocking APIs (and Task_sleep() is a blocking API).

    Richard Bland said:
    It seems that must be the case as I have implemented the delay by counting each time the clock thread runs and all is working.
    I've got alot to learn - sorry!

    No apology necessary, this is exactly what the TI E2E Forums are for.

    If you could, please mark your post (the one that mentions the Task_sleep()) as "Answered" so the Forum database and readers will benefit.

    I'm glad you found your issue.

    Regards,

    - Rob