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-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; 难道是为了让系统多跑一会{:lol:}
页:
[1]