MurphyZhao 发表于 2019-6-10 19:16:43

RT-Thread 中线程栈溢出检查的疑惑

本帖最后由 MurphyZhao 于 2019-6-10 19:19 编辑

    RT-Thread 中线程栈溢出检查在 void rt_schedule(void) 函数中,
但是,为什么仅检查了 to_thread,而不是检查 from_thread ?

    如果在 from_thread 栈溢出破坏了 to_thread 线程栈,检查 to_thread 栈溢出的时候并不会检查到异常,
但,切换到 to_thread 线程运行的时候,出现了错误,这个时候,定位到的错误在 to_thread,但确实是 from_thread 线程栈溢出导致的,这种情况是不是检查 from_thread 线程栈更加合理?

检查栈溢出的函数如下:

_rt_scheduler_stack_check(to_thread);

检查线程栈溢出的代码如下:


            if (to_thread != rt_current_thread)
            {
                /* if the destination thread is not the same as current thread */
                rt_current_priority = (rt_uint8_t)highest_ready_priority;
                from_thread         = rt_current_thread;
                rt_current_thread   = to_thread;

                RT_OBJECT_HOOK_CALL(rt_scheduler_hook, (from_thread, to_thread));

                if (need_insert_from_thread)
                {
                  rt_schedule_insert_thread(from_thread);
                }

                rt_schedule_remove_thread(to_thread);
                to_thread->stat = RT_THREAD_RUNNING | (to_thread->stat & ~RT_THREAD_STAT_MASK);

                /* switch to new thread */
                RT_DEBUG_LOG(RT_DEBUG_SCHEDULER,
                        ("[%d]switch to priority#%d "
                         "thread:%.*s(sp:0x%08x), "
                         "from thread:%.*s(sp: 0x%08x)\n",
                         rt_interrupt_nest, highest_ready_priority,
                         RT_NAME_MAX, to_thread->name, to_thread->sp,
                         RT_NAME_MAX, from_thread->name, from_thread->sp));

#ifdef RT_USING_OVERFLOW_CHECK
                _rt_scheduler_stack_check(to_thread);
#endif

                if (rt_interrupt_nest == 0)
                {
                  extern void rt_thread_handle_sig(rt_bool_t clean_state);

                  rt_hw_context_switch((rt_ubase_t)&from_thread->sp,
                            (rt_ubase_t)&to_thread->sp);

                  /* enable interrupt */
                  rt_hw_interrupt_enable(level);

#ifdef RT_USING_SIGNALS
                  /* check signal status */
                  rt_thread_handle_sig(RT_TRUE);
#endif
                  goto __exit;
                }
                else
                {
                  RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("switch in interrupt\n"));

                  rt_hw_context_switch_interrupt((rt_ubase_t)&from_thread->sp,
                            (rt_ubase_t)&to_thread->sp);
                }
            }

MurphyZhao 发表于 2019-6-11 18:21:42

本帖最后由 MurphyZhao 于 2019-6-12 08:35 编辑

特意去查了下 FreeRTOS 的源码,发现 FreeRTOS 会对 from_thread 进行堆栈溢出检查,还检查了两次(不知道分别做什么),代码如下:

                /* Check for stack overflow, if configured. */
                taskFIRST_CHECK_FOR_STACK_OVERFLOW();
                taskSECOND_CHECK_FOR_STACK_OVERFLOW();

                /* Select a new task to run using either the generic C or port
                optimised asm code. */
                taskSELECT_HIGHEST_PRIORITY_TASK();
                traceTASK_SWITCHED_IN();

                #if ( configUSE_NEWLIB_REENTRANT == 1 )
                {
                        /* Switch Newlib's _impure_ptr variable to point to the _reent
                        structure specific to this task. */
                        _impure_ptr = &( pxCurrentTCB->xNewLib_reent );
                }
                #endif /* configUSE_NEWLIB_REENTRANT */
        }
        _next_thread = (void *)pxCurrentTCB;

sunnydragon 发表于 2019-6-11 18:23:08

难道是为了让系统多跑一会{:lol:}
页: [1]
查看完整版本: RT-Thread 中线程栈溢出检查的疑惑